/*
 * Copyright© 2003-2019 浙江汇信科技有限公司, All Rights Reserved.
 */
package com.icinfo.cloud.provider.punish.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpStatus;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.common.core.page.PageResponse;
import com.icinfo.cloud.common.security.util.UserUtil;
import com.icinfo.cloud.provider.common.client.IUserCenterClient;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.constant.PunishMainServicePortUriConstant;
import com.icinfo.cloud.provider.common.dto.FileInfoSaveDto;
import com.icinfo.cloud.provider.common.enums.*;
import com.icinfo.cloud.provider.common.oss.service.IOssOperateService;
import com.icinfo.cloud.provider.common.utils.*;
import com.icinfo.cloud.provider.exception.BusinessException;
import com.icinfo.cloud.provider.punish.approval.vo.LineTerritoryInfoVo;
import com.icinfo.cloud.provider.punish.common.documentoperate.dto.FillAndConvertToPdfRequest;
import com.icinfo.cloud.provider.punish.common.documentoperate.enums.DocumentStatusEnum;
import com.icinfo.cloud.provider.punish.common.documentoperate.vo.DocumentCommonFormDataVo;
import com.icinfo.cloud.provider.punish.common.documentoperate.vo.DocumentCommonFormHtmlVo;
import com.icinfo.cloud.provider.punish.common.electricsent.dto.SendSmsDto;
import com.icinfo.cloud.provider.punish.common.seal.dto.FileSealInfoQueryDto;
import com.icinfo.cloud.provider.punish.config.dto.RelationWorkflowInfoRequest;
import com.icinfo.cloud.provider.punish.config.model.ConfigBusiParamDocumentColumn;
import com.icinfo.cloud.provider.punish.config.model.ConfigBusiParamDocumentInfo;
import com.icinfo.cloud.provider.punish.config.model.ConfigBusiParamMain;
import com.icinfo.cloud.provider.punish.config.model.SysDepartParam;
import com.icinfo.cloud.provider.punish.config.vo.BusiTableOperateVo;
import com.icinfo.cloud.provider.punish.csource.manage.enums.CaseSourceStatusEnum;
import com.icinfo.cloud.provider.punish.csource.manage.model.CaseSourceRegisterMainInfo;
import com.icinfo.cloud.provider.punish.csource.manage.vo.CaseSourcePartyInfoVo;
import com.icinfo.cloud.provider.punish.dto.*;
import com.icinfo.cloud.provider.punish.enums.ZtcSourceTypeEnum;
import com.icinfo.cloud.provider.punish.mapper.*;
import com.icinfo.cloud.provider.punish.model.*;
import com.icinfo.cloud.provider.punish.service.*;
import com.icinfo.cloud.provider.punish.strategy.appcase.BaseZtcSourceTypeHook;
import com.icinfo.cloud.provider.punish.strategy.document.enums.ZtcDocumentParamEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseDocumentNumberSerialDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.CaseStageEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.CaseStatusEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.CaseTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.HandlePersonTypeEnum;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.*;
import com.icinfo.cloud.provider.punish.vo.*;
import com.icinfo.cloud.xzcf.provider.member.userinfo.dto.UserDTO;
import com.icinfo.framework.common.web.Result;
import com.icinfo.framework.core.service.support.MyBatisServiceSupport;
import com.icinfo.framework.mybatis.mapper.entity.Example;
import com.icinfo.framework.mybatis.pagehelper.PageHelper;
import com.icinfo.framework.tools.utils.DateUtils;
import com.icinfo.framework.tools.utils.MapUtils;
import com.icinfo.framework.tools.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StopWatch;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.persistence.Column;
import java.io.File;
import java.lang.reflect.Field;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述: 案件文书记录表-TRJ app_case_before_document_record 对应的Service接口实现类.<br>
 *
 * @author framework generator
 * @date 2022年04月12日
 */
@Slf4j
@Service
@Transactional(rollbackFor = {Error.class, Exception.class})
public class AppCaseBeforeDocumentRecordServiceImpl extends MyBatisServiceSupport implements IAppCaseBeforeDocumentRecordService {
    /**
     * 日志记录器
     */
    private static final Logger logger = LoggerFactory.getLogger(AppCaseBeforeDocumentRecordServiceImpl.class);
    /**
     * success code
     */
    private static final int TWO_HUNDRED = 200;
    /**
     * code
     *
     * @param saveDto
     * @return
     */
    private static final String CODE = "code";
    @Value("${tzxzcfUrl}")
    private String tzxzcfUrl;
    @Value("${document.url}")
    private String url;

    @Value("${member.url}")
    private String member;
    @Value("${member.api.getTaskList}")
    private String getTaskListUrl;
    @Value("${member.api.getCheckTargetList}")
    private String getCheckTargetListUrl;
    @Value("${document.api.templateDetail}")
    private String templateDetail;
    @Value("${document.api.uploadConvertedPdf}")
    private String uploadConvertedPdf;
    @Value("${tzService.url}")
    private String tzServiceUrl;
    @Value("${isCheckHandleSign}")
    private String isCheckHandleSign;

    @Autowired
    private AppCaseBeforeDocumentRecordMapper appCaseBeforeDocumentRecordMapper;
    @Autowired
    private AppDocumentInfoDetailMapper appDocumentInfoDetailMapper;
    @Autowired
    private CaseDocumentNumberSerialMapper caseDocumentNumberSerialMapper;
    @Autowired
    private AppDocumentRelatedGoodsMapper appDocumentRelatedGoodsMapper;
    @Autowired
    private ConfigBusiParamDocumentInfoMapper configBusiParamDocumentInfoMapper;
    @Autowired
    private ConfigBusiParamDocumentColumnMapper configBusiParamDocumentColumnMapper;
    @Resource
    private ICaseDocumentRecordService caseDocumentRecordService;
    @Resource
    private IConfigBusiParamDocumentInfoService configBusiParamDocumentInfoService;
    @Resource
    private CaseDocumentRecordMapper caseDocumentRecordMapper;
    @Resource
    private ISysDepartParamService sysDepartParamService;
    @Resource
    private AppDocumentHandlePersonRecordMapper appDocumentHandlePersonRecordMapper;
    @Resource
    private AppCaseBeforeDocumentRecordHisMapper appCaseBeforeDocumentRecordHisMapper;
    @Resource
    private IAppDocumentHandlePersonRecordService appDocumentHandlePersonRecordService;
    @Resource
    private IConfigBusiParamMainService configBusiParamMainService;
    @Resource
    private IOssOperateService iOssOperateService;
    @Resource
    private ICaseSourceRegisterMainInfoService caseSourceRegisterMainInfoService;
    @Resource
    private ICaseMainInfoService caseMainInfoService;

    @Resource
    private AppDocumentSendRecordMapper appDocumentSendRecordMapper;
    @Resource
    private CasePartiesPersonInfoMapper casePartiesPersonInfoMapper;
    @Resource
    private CasePartiesLegalInfoMapper casePartiesLegalInfoMapper;

    @Resource
    private IDocCommonOperateService docCommonOperateService;

    @Resource
    private IAppCaseBeforeDocumentTemporaryRecordService appCaseBeforeDocumentTemporaryRecordService;

    @Resource
    private ApplicationContext applicationContext;

    @Resource
    private IUserCenterClient userCenterClient;

    @Resource
    private IAppDocumentInfoDetailService appDocumentInfoDetailService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> saveDocInfo(AppDocumentCommonSaveDto saveDto) {
        String kindCode = getKindCodeByCatalogId(saveDto.getDocumentCatalogCode());
        if (DocumentKindEnum.DOC_KIND_SDDZQRS.getCode().equals(kindCode) && ObjectUtil.isNotEmpty(saveDto.getCaseId())) {
            DocSaveAndRelatedCaseDto dto = new DocSaveAndRelatedCaseDto();
            BeanUtils.copyProperties(saveDto, dto);
            return caseDocumentRecordService.saveDocInfoAndRelatedCase(dto);
        }
        //生成文书id
        String docId = StringUtils.uuid();
        //========================================生成文书======================================================================
        //1、根据数据 先生成文书 ，包含文号，签名，签章，要生成两份文书 一份带签章供签字捺印，一份不带签章供蓝牙打印机使用
        //2、将数据保存到文书内容宽表，和文书记录表
        //3、若果哪一步失败，数据回滚，抛出异常
        UserDTO userDTO = getUser();
        List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = null;
        // 获取文书业务参数配置主表
        if (ObjectUtil.isNotEmpty(saveDto.getLineCode())) {
            kindCode = saveDto.getDocumentKindCode();
            configBusiParamDocumentInfos = getConfigBusiParamDocumentInfo(saveDto, userDTO);
        } else {
            configBusiParamDocumentInfos = getConfigBusiParamDocumentInfos(saveDto.getDocumentCatalogCode());
        }
        if (CollUtil.isEmpty(configBusiParamDocumentInfos)) {
            throw new com.icinfo.cloud.provider.common.exception.BusinessException("未匹配到业务关联文书配置记录");
        }
        //documentCatalogCode重新赋值
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo = configBusiParamDocumentInfos.get(0);
        saveDto.setDocumentCatalogCode(configBusiParamDocumentInfo.getDocumentCatalogCode());
        //获取文书模版code
        String templateCode = getTemplateCodeByDocumentCatalogCode(configBusiParamDocumentInfos, saveDto.getDocumentObjectType(), null);
        //获取当事人名称
        String partyName = getPartyName(saveDto);
        // 添加办案人签名
        HashMap<String, Object> paramMap = assemblyBaseParamMap(saveDto, userDTO, partyName);
        /**
         * ========================================数据保存======================================================================
         */
        //构建生成文书参数
        FillAndConvertToPdfRequest pdfRequest = assemblePdfRequest(templateCode, kindCode, paramMap);
        //生成文书并保存文书记录
        AppCaseBeforeDocumentRecordNew documentRecord = generateDocumentAndSaveRecord(saveDto, pdfRequest, docId, configBusiParamDocumentInfos.get(0), partyName);
        // 文书内容表 保存更新，目前更新不做,做的话新增docId 字段，走分支逻辑
        if (generateDetailResult(saveDto, docId) != 1) {
            throw new BusinessException("文书提交保存失败");
        }
        //关联物品集合
        relationGoodsList(saveDto, docId);
        //执法人员信息处理
        dealDocumentHandlePersonRecord(saveDto, docId);
        //若需要更新则根据配置更新相关数据
        operateBusiTableByDocumentCatalogCode(saveDto);
        //清空暂存
        appCaseBeforeDocumentTemporaryRecordService.removeCurrentUserTemporaryRecord(saveDto.getDocumentCatalogCode(), saveDto.getSourceType(), saveDto.getSourceId());
        //默认处罚直通车来源
        ZtcSourceTypeEnum sourceType = Optional.ofNullable(saveDto.getSourceType()).orElse(ZtcSourceTypeEnum.CF_ZTC);
        BaseZtcSourceTypeHook.getHook(sourceType, applicationContext)
                .appCaseSaveHook(new CheckObjectZtcSourceTypeDto()
                        .setSourceId(saveDto.getSourceId())
                        .setDocumentId(docId)
                        .setSourceType(sourceType)
                        .setTaskOrgId(saveDto.getTaskOrgId())
                        .setDocumentKindEnum(DocumentKindEnum.getEnumByCode(kindCode)));
        // 组装返回
        return assemblyReturn(documentRecord, docId, configBusiParamDocumentInfo);
    }

    /**
     * 通过catalogCode获取文书kindCode
     */
    private String getKindCodeByCatalogId(String catalogId) {
        ConfigBusiParamDocumentInfo detailByDocumentCatalogCode = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(catalogId);
        return detailByDocumentCatalogCode.getDocumentKindCode();
    }

    /**
     * 组装返回
     */
    private static Map<String, Object> assemblyReturn(AppCaseBeforeDocumentRecordNew documentRecord, String docId, ConfigBusiParamDocumentInfo configBusiParamDocumentInfo) {
        Map<String, Object> resultMap = new HashMap<>(16);
        resultMap.put("success", "true");
        resultMap.put("pdfSealUrl", documentRecord.getDocumentUrlAfterSeal());
        resultMap.put("unSealPdfUrl", documentRecord.getDocumentUrl());
        resultMap.put("docId", docId);
        resultMap.put("showEditButtonType", configBusiParamDocumentInfo.getIsAllowEdit());
        return resultMap;
    }

    /**
     * 获取文书业务参数配置主表
     */
    private List<ConfigBusiParamDocumentInfo> getConfigBusiParamDocumentInfo(AppDocumentCommonSaveDto saveDto, UserDTO userDTO) {
        //根据文书目录编码获取模板code
        //根据kindCode和busiParamId获取文书目录配置
        String kindCode = saveDto.getDocumentKindCode();
        RelationWorkflowInfoRequest request = new RelationWorkflowInfoRequest();
        request.setApplyAreaCode(userDTO.getAreaCode());
        String applyFieldCode = saveDto.getLineCode().substring(0, 4);
        request.setApplyFieldCode(applyFieldCode);
        if ("A037".equals(applyFieldCode)) {
            request.setApplyAreaCode(null);
        }
        List<ConfigBusiParamMain> configBusiParamMainList = configBusiParamMainService.getConfigBusiParamMainList(request);
        ConfigBusiParamMain configBusiParamMain = configBusiParamMainList.stream().findFirst().orElse(null);
        if (Objects.isNull(configBusiParamMain)) {
            throw new BusinessException("未匹配业务参数配置主表信息");
        }
        String busiParamId = configBusiParamMain.getId();
        Example example = new Example(ConfigBusiParamDocumentInfo.class);
        example.createCriteria().andEqualTo("busiParamId", busiParamId)
                .andEqualTo("documentKindCode", kindCode)
                .andEqualTo("applyGroup", "ZTC");
        return configBusiParamDocumentInfoMapper.selectByExample(example);
    }


    /**
     * 获取直通车文书当事人名称
     *
     * @param saveDto 保存对象
     * @return
     */
    private static String getPartyName(AppDocumentCommonSaveDto saveDto) {
        // 添加公用固定字段
        String partyName = "";
        if (Constant.STRING_1.equals(saveDto.getDocumentObjectType())) {
            partyName = saveDto.getPersonName();
        } else {
            partyName = saveDto.getEntName();
        }
        return partyName;
    }

    private void relationGoodsList(AppDocumentCommonSaveDto saveDto, String docId) {
        //关联物品表
        // 目前更新不做，docId 字段，走分支逻辑
        String gl = "goodsList";
        if (!ObjectUtils.isEmpty(saveDto.getDataMap().get(gl))) {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(saveDto.getDataMap()));
            JSONArray array = jsonObject.getJSONArray(gl);
            for (int i = 0; i < array.size(); i++) {
                AppDocumentRelatedGoods goods = JSON.parseObject(array.getJSONObject(i).toJSONString(), AppDocumentRelatedGoods.class);
                goods.setDocumentId(docId);
                goods.setId(StringUtils.uuid());
                appDocumentRelatedGoodsMapper.insert(goods);
            }
        }
    }

    /**
     * 构建生成直通车文书参数
     *
     * @param templateCode 文书模版code
     * @param kindCode     文书类型code
     * @param paramMap     文书参数
     * @return
     */
    private static FillAndConvertToPdfRequest assemblePdfRequest(String templateCode, String kindCode, HashMap<String, Object> paramMap) {
        FillAndConvertToPdfRequest pdfRequest = new FillAndConvertToPdfRequest();
        pdfRequest.setTemplateCode(templateCode);

        if (DocumentKindEnum.DOC_KIND_DK2LJDLXJDS.getCode().equals(kindCode) || DocumentKindEnum.DOC_KIND_DK2XZQZZXXCBL.getCode().equals(kindCode)) {
            //立即代履行决定书和行政强制执行现场笔录标准模板
            if (DocumentKindEnum.DOC_KIND_DK2LJDLXJDS.getCode().equals(kindCode)) {
                String performTime = (String) paramMap.get("performTime");
                boolean b = DateUtil.compDate(performTime);
                if (b) {
                    throw new BusinessException("违法日期不能大于当前日期");
                }
            }
            if (DocumentKindEnum.DOC_KIND_DK2XZQZZXXCBL.getCode().equals(kindCode)) {
                String startTime = DateUtil.formatDateStr((String) paramMap.get("startTime"));
                String endTime = DateUtil.formatDateStr((String) paramMap.get("endTime"));
                paramMap.put("time", startTime.trim() +
                        "至" + endTime.substring(endTime.length() - 6, startTime.length()));
            }
            pdfRequest.setTemplateType(DocumentTemplateKindEnum.STANDARD_TEMPLATE.getCode());
        }
        pdfRequest.setParamMap(paramMap);
        return pdfRequest;
    }

    /**
     * 办案直通车执法人员信息处理
     *
     * @param saveDto
     */
    private void dealDocumentHandlePersonRecord(AppDocumentCommonSaveDto saveDto, String docId) {
        //没有选择协办人员的文书不保存执法人员记录
        if (ObjectUtils.isEmpty(saveDto.getAssistHandleUserId())) {
            return;
        }
        //主办
        AppDocumentHandlePersonRecord mainPersonRecord = new AppDocumentHandlePersonRecord();
        mainPersonRecord.setHandlePersonType(HandlePersonTypeEnum.MAIN.getCode());
        mainPersonRecord.setHandlePersonId(saveDto.getMainHandleUserId());
        mainPersonRecord.setHandlePersonName(saveDto.getMainHandleUser());
        mainPersonRecord.setHandlePersonTel(saveDto.getMainHandleTel());
        mainPersonRecord.setHandleOrgCode(saveDto.getMainHandleOrgCode());
        mainPersonRecord.setHandleOrgName(saveDto.getMainHandleOrgName());
        mainPersonRecord.setHandleDeptCode(saveDto.getMainHandleDeptCode());
        mainPersonRecord.setHandleDeptName(saveDto.getMainHandleDeptName());
        mainPersonRecord.setAppDocumentId(docId);
        mainPersonRecord.setDingId(saveDto.getMainHandleDingId());
        mainPersonRecord.setId(BaseUtil.createUid());
        appDocumentHandlePersonRecordMapper.insertSelective(mainPersonRecord);
        //协办
        AppDocumentHandlePersonRecord assistPersonRecord = new AppDocumentHandlePersonRecord();
        assistPersonRecord.setHandlePersonType(HandlePersonTypeEnum.ASSIST.getCode());
        assistPersonRecord.setHandlePersonId(saveDto.getAssistHandleUserId());
        assistPersonRecord.setHandlePersonName(saveDto.getAssistHandleUser());
        assistPersonRecord.setHandlePersonTel(saveDto.getAssistHandleTel());
        assistPersonRecord.setHandleOrgCode(saveDto.getAssistHandleOrgCode());
        assistPersonRecord.setHandleOrgName(saveDto.getAssistHandleOrgName());
        assistPersonRecord.setHandleDeptCode(saveDto.getAssistHandleDeptCode());
        assistPersonRecord.setHandleDeptName(saveDto.getAssistHandleDeptName());
        assistPersonRecord.setAppDocumentId(docId);
        assistPersonRecord.setDingId(saveDto.getAssistHandleDingId());
        assistPersonRecord.setId(BaseUtil.createUid());
        appDocumentHandlePersonRecordMapper.insertSelective(assistPersonRecord);
    }


    /**
     * 保存文书详情表
     *
     * @param saveDto
     * @param docId
     * @return
     */
    private int generateDetailResult(AppDocumentCommonSaveDto saveDto, String docId) {
        // 当事人信息校验
        checkParties(saveDto);
        AppDocumentInfoDetail appDocumentInfoDetail = new AppDocumentInfoDetail();
        BeanUtils.copyProperties(saveDto, appDocumentInfoDetail);
        appDocumentInfoDetail.setPartyName(StringUtils.isBlank(saveDto.getEntName()) ? saveDto.getPersonName() : saveDto.getEntName());
        appDocumentInfoDetail.setId(docId);
        appDocumentInfoDetail.setDocumentCatalogCode(saveDto.getDocumentCatalogCode());
        appDocumentInfoDetail.setPartyType(saveDto.getDocumentObjectType());
        appDocumentInfoDetail.setCreateTime(LocalDateTime.now());
        UserDTO userDTO = UserUtil.getUserInfo();
        appDocumentInfoDetail.setCreator(userDTO.getUserId().toString());
        appDocumentInfoDetail.setCreateTime(LocalDateTime.now());
        appDocumentInfoDetail.setUpdateTime(LocalDateTime.now());
        appDocumentInfoDetail.setUpdator(userDTO.getUserId().toString());
        //设置关联任务信息
        List<AssociatedTaskVo> associatedInfo = Optional.ofNullable(saveDto.getAssociatedInfo()).orElse(Collections.emptyList());
        //初始化关联任务时间
        associatedInfo.forEach(AssociatedTaskVo::initRelationTime);
        appDocumentInfoDetail.setAssociatedInfo(JSON.toJSONString(associatedInfo));

        // 询问通知书 复选框特殊梳理
        wxtzsCheckBoxsDeal(saveDto, appDocumentInfoDetail);

        // 反射设值
        try {
            List<BusiTableOperateVo> busiTableOperateVoList = configBusiParamDocumentColumnMapper.selectTableNameListByDocumentCatalogCode(saveDto.getDocumentCatalogCode());
            // 获取属性
            Field[] fields = AppDocumentInfoDetail.class.getDeclaredFields();
            HashMap<String, Object> insertMap = saveDto.getDataMap();
            HashMap<String, Object> insertTransferMap = new HashMap<>(64);
            /**
             * 带经纬度的地址，用统一的key 映射column表，根据文书目录编码判断区分
             */
            String commonLatAndLgtAddr = "addressWithLatAndLgt";
            if (ObjectUtil.isNotEmpty(insertMap.get(commonLatAndLgtAddr))) {
                JSONObject addrJson = JSONObject.parseObject(JSON.toJSONString(insertMap.get(commonLatAndLgtAddr)));
                if (ObjectUtil.isNotEmpty(addrJson)) {
                    // {address: "拱墅区西溪街道蓝天商务中心", lng: 120.14989, lat: 30.27751}
                    insertMap.put("ZTC_COMMON_ADDRESS", addrJson.getString("address"));
                    insertMap.put("ZTC_COMMON_LAT_AND_LGT", addrJson.getString("lng").concat(",").concat(addrJson.getString("lat")));
                }
            }
            // 转换key名
            for (BusiTableOperateVo busiTableOperateVo : busiTableOperateVoList) {
                Example example = new Example(ConfigBusiParamDocumentColumn.class);
                example.createCriteria().andEqualTo("documentCatalogCode", saveDto.getDocumentCatalogCode()).andEqualTo("busiTableNameEn", busiTableOperateVo.getBusiTableNameEn());
                List<ConfigBusiParamDocumentColumn> configBusiParamDocumentColumnList = configBusiParamDocumentColumnMapper.selectByExample(example);
                for (ConfigBusiParamDocumentColumn column : configBusiParamDocumentColumnList) {
                    for (Map.Entry<String, Object> entry : insertMap.entrySet()) {
                        if (entry.getKey().equals(column.getDocumentTemplateFieldEn())) {
                            insertTransferMap.put(column.getBusiColumnEn(), entry.getValue());
                        }
                    }
                }
            }
            // 将日期转换为正确类型
            for (Map.Entry<String, Object> entry : insertTransferMap.entrySet()) {
                if (entry.getKey().contains("date") || entry.getKey().contains("DATE") || entry.getKey().contains("time") || entry.getKey().contains("TIME")) {
                    if (entry.getValue() != null) {
                        if (entry.getValue().toString().contains("年")) {
                            if (entry.getValue().toString().contains("时")) {
                                entry.setValue(LocalDateTime.parse(entry.getValue().toString(), DateTimeFormatter.ofPattern("yyyy年M月d日H时mm分ss秒")));
                            } else {
                                entry.setValue(LocalDate.parse(entry.getValue().toString(), DateTimeFormatter.ofPattern("yyyy年M月d日")).atStartOfDay());
                            }
                        } else {
                            entry.setValue(LocalDateTime.parse(entry.getValue().toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                        }
                    }
                }
            }
            // 反射设值
            for (Field f : fields) {
                if (f.isAnnotationPresent(Column.class)) {
                    for (Map.Entry<String, Object> entry : insertTransferMap.entrySet()) {
                        String mapKey = entry.getKey();
                        Object mapValue = entry.getValue();
                        // 根据属性上注解名
                        if (f.getAnnotation(Column.class).name().equals(mapKey)) {
                            Field insertField = appDocumentInfoDetail.getClass().getDeclaredField(f.getName());
                            insertField.setAccessible(true);
                            insertField.set(appDocumentInfoDetail, mapValue);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("保存详情表反射设值失败：", e);
            throw new BusinessException(e.getMessage());
        }
        return appDocumentInfoDetailMapper.insert(appDocumentInfoDetail);
    }

    /**
     * 询问通知书 复选框特殊梳理
     *
     * @param saveDto
     * @param appDocumentInfoDetail
     */
    private void wxtzsCheckBoxsDeal(AppDocumentCommonSaveDto saveDto, AppDocumentInfoDetail appDocumentInfoDetail) {
        String xwtzs = "XWTZS";
        if (saveDto.getDocumentCatalogCode().contains(xwtzs)) {
            List<String> acceptInquireCarryMaterialList = new ArrayList<>();
            //获取参数配置
            List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = getConfigBusiParamDocumentInfos(saveDto.getDocumentCatalogCode());
            String templateCode = getTemplateCodeByDocumentCatalogCode(configBusiParamDocumentInfos, "", null);
            Map<String, Object> templateDetailConfig = getTemplateDetailConfig(templateCode);
            if (ObjectUtil.isNotEmpty(templateDetailConfig.get("templateFieldConfigs"))) {
                Map<String, Object> templateFieldConfigs = JSONObject.parseObject(templateDetailConfig.get("templateFieldConfigs").toString(), Map.class);
                //遍历处理复选框
                Set<String> templateDetailMapSet = templateFieldConfigs.keySet();
                HashMap<String, Object> dataMap = saveDto.getDataMap();
                for (String key : templateDetailMapSet) {
                    JSONObject fieldConfigJson = JSON.parseObject(templateFieldConfigs.get(key).toString());
                    // CHECKBOX("8", "复选框")
                    if ("8".equals(fieldConfigJson.getString("controlType"))
                            && "ea4e70f9-2717-4f31-fcd2-6ea8765b8754".equals(fieldConfigJson.getString("controlGroupId"))) {
                        if (Constant.STRING_TRUE.equals(dataMap.get(key).toString())) {
                            acceptInquireCarryMaterialList.add(fieldConfigJson.getString("templateFieldCn"));
                        }

                    }
                }
            }
//            String yyzz = "xwtzs_yyzz";
//            if (saveDto.getDataMap().get(yyzz) != null){
//                acceptInquireCarryMaterial.add(saveDto.getDataMap().get(yyzz).toString());
//            }
//            String zzjgdmz = "xwtzs_zzjgdmz";
//            if (saveDto.getDataMap().get(zzjgdmz) != null){
//                acceptInquireCarryMaterial.add(saveDto.getDataMap().get(zzjgdmz).toString());
//            }
//            String fddbrzs = "xwtzs_fddbrzs";
//            if (saveDto.getDataMap().get(fddbrzs) != null){
//                acceptInquireCarryMaterial.add(saveDto.getDataMap().get(fddbrzs).toString());
//            }
//            String brsfzj = "xwtzs_brsfzj";
//            if (saveDto.getDataMap().get(brsfzj) != null){
//                acceptInquireCarryMaterial.add(saveDto.getDataMap().get(brsfzj).toString());
//            }
//            String sqwts = "xwtzs_sqwts";
//            if (saveDto.getDataMap().get(sqwts) != null){
//                acceptInquireCarryMaterial.add(saveDto.getDataMap().get(sqwts).toString());
//            }
//            String xgxkzj = "xwtzs_xgxkzj";
//            if (saveDto.getDataMap().get(xgxkzj) != null){
//                acceptInquireCarryMaterial.add(saveDto.getDataMap().get(xgxkzj).toString());
//            }
//            String otherfile = "xwtzs_otherfile";
//            if (saveDto.getDataMap().get(otherfile) != null){
//                acceptInquireCarryMaterial.add(saveDto.getDataMap().get(otherfile).toString());
//            }
            String acceptInquireCarryMaterial = "";
            if (acceptInquireCarryMaterialList.size() > 0) {
                acceptInquireCarryMaterial = acceptInquireCarryMaterialList.stream().collect(Collectors.joining(","));
            }

            appDocumentInfoDetail.setAcceptInquireCarryMaterial(acceptInquireCarryMaterial);
        }
    }

    /**
     * 当事人信息校验
     *
     * @param saveDto
     */
    private void checkParties(AppDocumentCommonSaveDto saveDto) {
        if (Constant.STRING_1.equals(saveDto.getDocumentObjectType())) {
            if (StringUtils.isBlank(saveDto.getPersonCertNo()) || StringUtils.isBlank(saveDto.getPersonName())
                    || StringUtils.isBlank(saveDto.getPersonCertType())) {
                throw new BusinessException("文书对象自然人信息必填");
            }
        }

        if (Constant.STRING_2.equals(saveDto.getDocumentObjectType())) {
            if (StringUtils.isBlank(saveDto.getEntName())) {
                throw new BusinessException("文书对象单位名称必填");
            }
            if (StringUtils.isBlank(saveDto.getUnicode())) {
                throw new BusinessException("文书对象单位统一社会信用代码必填");
            }
            if (StringUtils.isBlank(saveDto.getLegalName())) {
                throw new BusinessException("文书对象单位法定代表人信息必填");
            }
        }
    }


    /**
     * 生成文书并保存文书记录表
     *
     * @param saveDto                     保存参数
     * @param docId                       文书记录id
     * @param configBusiParamDocumentInfo 参数配置
     * @param partyName                   当事人名称
     * @return
     */
    private AppCaseBeforeDocumentRecordNew generateDocumentAndSaveRecord(AppDocumentCommonSaveDto saveDto, FillAndConvertToPdfRequest pdfRequest, String docId, ConfigBusiParamDocumentInfo configBusiParamDocumentInfo, String partyName) {
        //添加文号
        String documentNumber = getDocumentNumber(docId, saveDto.getDocumentKindCode(), saveDto.getLineCode(), saveDto.getLineTypeCode());
        //设置文书参数中的文书号
        pdfRequest.getParamMap().put("documentNumber", documentNumber);
        AppCaseBeforeDocumentRecordNew caseDocumentRecord = new AppCaseBeforeDocumentRecordNew();
        //设置文书号，后续在生成文书时会使用
        caseDocumentRecord.setDocumentNumber(documentNumber);
        //获取用户信息
        UserDTO userDTO = getUser();
        //生成文书，并填充文书记录
        generateStandardAndNarrowDocumentAndFillRecord(userDTO, pdfRequest, configBusiParamDocumentInfo, caseDocumentRecord, false);
        caseDocumentRecord.setCreateTime(LocalDateTime.now());
        caseDocumentRecord.setId(docId);
        caseDocumentRecord.setDocumentCatalogCode(saveDto.getDocumentCatalogCode());
        caseDocumentRecord.setDocumentCreateTime(LocalDateTime.now());
        caseDocumentRecord.setCreateTime(LocalDateTime.now());
        caseDocumentRecord.setDocumentSignstampedStatus(DocumentStatusEnum.WAIT_TO_CONFIRM.getCode());
        caseDocumentRecord.setCreateUserName(userDTO.getRealName());
        caseDocumentRecord.setCreateUserId(userDTO.getUserId().toString());
        caseDocumentRecord.setUpdator(userDTO.getUserId().toString());
        caseDocumentRecord.setUpdateTime(LocalDateTime.now());
        caseDocumentRecord.setOrgCode(userDTO.getOrgCode());
        caseDocumentRecord.setOrgName(userDTO.getOrgName());
        caseDocumentRecord.setDeptCode(userDTO.getDeptCode());
        caseDocumentRecord.setDocumentName(configBusiParamDocumentInfo.getDocumentCatalogName());
        caseDocumentRecord.setDocumentTittle(partyName + "的" + configBusiParamDocumentInfo.getDocumentCatalogName());
        // 组装来源相关数据
        assembleRecordSource(saveDto, caseDocumentRecord);
        //插入数据
        appCaseBeforeDocumentRecordMapper.insert(caseDocumentRecord);
        return caseDocumentRecord;
    }

    /**
     * 组装直通车文书来源数据
     *
     * @param saveDto
     * @param caseDocumentRecord
     */
    private static void assembleRecordSource(AppDocumentCommonSaveDto saveDto, AppCaseBeforeDocumentRecordNew caseDocumentRecord) {
        ZtcSourceTypeEnum ztcSourceTypeEnum = Optional.ofNullable(saveDto.getSourceType()).orElse(ZtcSourceTypeEnum.CF_ZTC);
        caseDocumentRecord.setSourceType(ztcSourceTypeEnum.getCode());
        if (!ZtcSourceTypeEnum.CHECK_OBJECT.equals(ztcSourceTypeEnum)) {
            return;
        }
        if (StrUtil.isBlank(saveDto.getSourceId()) || StrUtil.isBlank(saveDto.getTaskOrgId())) {
            throw new BusinessException("检查相关sourceId或taskOrgId不能为空！");
        }
        ZtcCheckObjectContentDto dto = new ZtcCheckObjectContentDto();
        dto.setSourceId(saveDto.getSourceId());
        dto.setTaskOrgId(saveDto.getTaskOrgId());
        caseDocumentRecord.setSourceContent(JSON.toJSONString(dto));
    }


    /**
     * 文件签章并上传到oss
     *
     * @param queryDto 查询dto
     * @return {@link Map<String, String> }
     * @author shishengyao
     * @date 2022/03/07
     */
    @Override
    public String dealFileSeal(FileSealInfoQueryDto queryDto) {
        //签章
        Map<String, String> headers = HeaderUtil.headerInfo();
        String param = JSON.toJSONString(queryDto);
        String response = HttpUtil.createPost(tzServiceUrl.concat("punish/seal/getFileAfterSealString")).addHeaders(headers).body(param).execute().body();
        Result result = JSON.parseObject(response, Result.class);
        if (TWO_HUNDRED != result.getCode()) {
            logger.info("warn fileSealService,result:{}", result.getMessage());
            throw new BusinessException(result.getMessage());
        }
        return result.getData().toString();
    }


    /**
     * 获取转换生成pdf并上传到oss的地址
     *
     * @param pdfRequest pdf格式的请求
     * @return {@link String }
     * @author shishengyao
     * @date 2022/02/25
     */
    @Override
    public Map<String, String> getConvertedPdfUrl(FillAndConvertToPdfRequest pdfRequest) {
        Map<String, String> headers = HeaderUtil.headerInfo();
        Map<String, Object> paramMap = new HashMap<>(16);
        paramMap.put("templateCode", pdfRequest.getTemplateCode());
        paramMap.put("paramMap", pdfRequest.getParamMap());
        if (!ObjectUtils.isEmpty(pdfRequest.getTemplateType())) {
            paramMap.put("templateType", pdfRequest.getTemplateType());
        } else {
            paramMap.put("templateType", "narrow");
        }
        if (YesOrNoEnum.YES.getCode().equals(pdfRequest.getIsGeneratePcDoc())) {
            paramMap.put("templateType", "");
        }
        String result = HttpUtil.createPost(url.concat(uploadConvertedPdf)).addHeaders(headers).body(JSON.toJSONString(paramMap)).contentType("application/json").execute().body();
        if (com.icinfo.framework.tools.utils.StringUtils.isNotBlank(result)) {
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (TWO_HUNDRED == jsonObject.getIntValue(CODE)) {
                String dataResult = jsonObject.get("data").toString();
                JSONObject data = JSON.parseObject(dataResult);
                Map<String, String> resultMap = new HashMap<>(16);
                //文书地址
                resultMap.put("fileUrl", data.getString("fileUrl"));
                //生成文书base64
                resultMap.put("fileBase64", data.getString("fileBase64"));
                return resultMap;
            } else {
                throw new BusinessException(jsonObject.getString("message"));
            }
        } else {
            throw new BusinessException("文书生成服务网络异常");
        }
    }

    /**
     * 描述：添加办案人签名
     *
     * @param saveDto 保存dto
     * @return {@link Map<String, Object> }
     * @author cyy
     * @date 2022/03/10
     */
    private HashMap<String, Object> addHandlerSigns(AppDocumentCommonSaveDto saveDto) {
        HashMap<String, Object> paramMap = saveDto.getDataMap();
        paramMap.put("mainHandleSignPic", getHandleSignData(saveDto.getMainHandleUserId()));
        if (ObjectUtil.isNotEmpty(saveDto.getAssistHandleUserId())) {
            paramMap.put("assistHandleSignPic", getHandleSignData(saveDto.getAssistHandleUserId()));
        } else {
            paramMap.put("assistHandleSignPic", "");
        }
        paramMap.put("handlePersonSignDate", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年M月d日")));
        return paramMap;
    }


    /**
     * 获得文书配置
     *
     * @param catalogCode
     * @return
     */
    public List<ConfigBusiParamDocumentInfo> getConfigBusiParamDocumentInfos(String catalogCode) {
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo = new ConfigBusiParamDocumentInfo();
        configBusiParamDocumentInfo.setDocumentCatalogCode(catalogCode);
        configBusiParamDocumentInfo.setIsDeleted("0");
        List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = configBusiParamDocumentInfoMapper.select(configBusiParamDocumentInfo);
        return configBusiParamDocumentInfos;
    }

    /**
     * 获得文书模板
     *
     * @param partyType
     * @param configBusiParamDocumentInfos
     * @return
     */
    @Override
    public String getTemplateCodeByDocumentCatalogCode(List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos, String partyType, String caseType) {
        String templateCode = "";
        if (ObjectUtil.isNotEmpty(configBusiParamDocumentInfos)) {
            ConfigBusiParamDocumentInfo info = configBusiParamDocumentInfos.get(0);
            boolean flag = CaseTypeEnum.SIMPLE_QUICK.getCode().equals(caseType);
            //根据当事人类型获取对应的模板
            if (Constant.STRING_1.equals(partyType)) {
                //个人
                templateCode = flag ? info.getFastTemplatePersonCode() : info.getTemplatePersonCode();
            } else if (Constant.STRING_2.equals(partyType)) {
                //法人
                templateCode = flag ? info.getFastTemplatePersonCode() : info.getTemplateLegalCode();
            } else {
                templateCode = flag ? info.getFastTemplatePersonCode() : info.getTemplatePersonCode();
            }
        }
        return templateCode;
    }

    @Override
    public DocumentCommonFormHtmlVo getDocumentFormHtml(DocCommonHtmlRequest request) {

        //根据文书目录编码获取模板code
        //显示的模板 通用不区分个人企业
        List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = getConfigBusiParamDocumentInfos(request.getDocumentCatalogCode());
        String templateCode = getTemplateCodeByDocumentCatalogCode(configBusiParamDocumentInfos, "", null);
        //从文书管理 获取模板code
        DocumentCommonFormHtmlVo vo = new DocumentCommonFormHtmlVo();
        Map<String, String> headers = HeaderUtil.headerInfo();
        Map<String, Object> paramMap = new HashMap<>(8);
        paramMap.put("templateCode", templateCode);
        paramMap.put("templateType", "narrow");
        String result = HttpUtil.createPost(url.concat(templateDetail)).addHeaders(headers).body(JSON.toJSONString(paramMap)).contentType("application/json").execute().body();
        if (StringUtils.isNotBlank(result)) {
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (TWO_HUNDRED == jsonObject.getInteger(CODE)) {
                JSONObject data = JSON.parseObject(jsonObject.get("data").toString());
                //获取返回的html内容
                Map<String, Object> objectMap = JSON.parseObject(data.getString("templateFieldConfigs"));
                vo.setHtmlContent(data.getString("standardFormTemplate") == null ? "" : data.getString("standardFormTemplate"));
                vo.setTemplateConfigMap(objectMap);
            } else {
                logger.info("调用文书模板配置失败，result:{}", result);
            }
        }
        return vo;
    }

    /**
     * 获取文书内容
     *
     * @param dto
     * @return
     */
    @Override
    public DocumentCommonFormDataVo getCommonDocumentFormData(DocCommonHtmlRequest dto) {
        DocumentCommonFormDataVo vo = new DocumentCommonFormDataVo();
        /**
         * 暂时未用
         *
         *         List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = getConfigBusiParamDocumentInfos(request.getDocumentCatalogCode());//
         *         String templateCode = getTemplateCodeByDocumentCatalogCode(configBusiParamDocumentInfos,"");//
         *         //从文书管理 获取模板code
         *         String result = HttpClientUtil.executeRequest(url + templateDetail + templateCode + "?templateCode=" + templateCode, "POST", null, null);//
         *         if (StringUtils.isNotBlank(result)) {}//
         *
         */
        // 目前没有案件关联 不用自动填充数据只要返回已提交数据
        AppCaseBeforeDocumentRecordNew appCaseBeforeDocumentRecordNew = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(dto.getDocumentId());
        if (appCaseBeforeDocumentRecordNew != null) {
            JSONObject jsonObject = JSON.parseObject(appCaseBeforeDocumentRecordNew.getDocumentContent());
            UserDTO user = UserUtil.getUserInfo();
            jsonObject.put("ORG_NAME", user.getOrgName());
            jsonObject.put("ZGT_ORG_NAME", user.getOrgName());
            vo.setDataMap(jsonObject);
        } else {
            //暂存end
            vo.setOperateType(RecordSaveTypeEnum.ADD.getCode());
            Map<String, Object> resultData = dealCommonDocumentFormData(dto);
            vo.setDataMap(resultData);
        }

        // 为检查对象文书填充对应数据
        assembleCheckObject(dto, vo);
        return vo;
    }

    /**
     * 为检查对象文书填充对应数据
     *
     * @param dto
     * @param vo
     */
    private void assembleCheckObject(DocCommonHtmlRequest dto, DocumentCommonFormDataVo vo) {
        // 通过catalogCode获取kindCode
        ConfigBusiParamDocumentInfo detailByDocumentCatalogCode = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(dto.getDocumentCatalogCode());
        String kindCode = detailByDocumentCatalogCode.getDocumentKindCode();
        // 处理来源
        ZtcSourceTypeEnum ztcSourceTypeEnum = Optional.ofNullable(dto.getSourceTypeEnum()).orElse(ZtcSourceTypeEnum.CF_ZTC);
        // 文书类型不为责令改正通知书 || 来源是直通车
        if (!DocumentKindEnum.DOC_KIND_ZLGZTZS.getCode().equals(kindCode) || ZtcSourceTypeEnum.CF_ZTC.equals(ztcSourceTypeEnum)) {
            return;
        }
        // 获取检查对象信息
        CheckObjectInfoBySourceIdDto request = new CheckObjectInfoBySourceIdDto();
        request.setSourceId(dto.getSourceId());
        request.setTaskOrgId(dto.getTaskOrgId());
        TaskClientVO clientVO = userCenterClient.getCheckObjectInfoBySourceId(request);
        if (Objects.isNull(clientVO)) {
            return;
        }
        // 将检查对象的检查地点与日期填充
        Map<String, Object> dataMap = assembleCheckObjectAddressAndDate(vo, clientVO);
        vo.setDataMap(dataMap);
    }

    /**
     * 组装检查对象的案发时间与案发地址
     */
    private static Map<String, Object> assembleCheckObjectAddressAndDate(DocumentCommonFormDataVo vo, TaskClientVO clientVO) {
        Map<String, Object> dataMap = vo.getDataMap();
        dataMap.put("ZGT_AFRQ", clientVO.getCheckDate());
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("address", clientVO.getAddress());
        jsonObject.put("lat", Constant.INTEGER_0);
        jsonObject.put("lng", Constant.INTEGER_0);
        dataMap.put("addressWithLatAndLgt", jsonObject);
        return dataMap;
    }


    private Map<String, Object> dealCommonDocumentFormData(DocCommonHtmlRequest request) {
        Map<String, Object> resultData = new HashMap<>();
        //查询配置信息
        List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = getConfigBusiParamDocumentInfos(request.getDocumentCatalogCode());
        String templateCode = getTemplateCodeByDocumentCatalogCode(configBusiParamDocumentInfos, "", null);
        Map<String, Object> templateConfigDetail = getTemplateDetailConfig(templateCode);
        //根据表名，分组查询所需字段数据，放入一个map中
        Map<String, String> sourceDataMap = new HashMap<>();
        if (ObjectUtil.isNotEmpty(templateConfigDetail.get("sourceFieldInfos"))) {
            Map<String, Object> sourceFieldInfos = JSON.parseObject(templateConfigDetail.get("sourceFieldInfos").toString());
            // 从表中获取数据
            sourceDataMap = getSourceDataMap(sourceFieldInfos, request);
        }

        if (ObjectUtil.isNotEmpty(templateConfigDetail.get("templateFieldConfigs"))) {

            Map templateFieldConfigs = JSON.parseObject(templateConfigDetail.get("templateFieldConfigs").toString());
            Set<String> templateConfigSet = templateFieldConfigs.keySet();
            //循环给自动填充的字段赋值
            for (String configKey : templateConfigSet) {
                String value = "";
                JSONObject paramMap = JSON.parseObject(templateFieldConfigs.get(configKey).toString());
                if (ObjectUtil.isNotEmpty(paramMap.get("isAutoData")) && Constant.WHETHER_STRING_YES.equals(paramMap.get("isAutoData"))) {
                    String dataGenerateRule = paramMap.getString("dataGenerateRule");
                    //自动数据来源，SOURCE_ARTIFICIAL页面填充，SOURCE_SYSTEM系统字段
                    if ("SOURCE_ARTIFICIAL".equals(paramMap.getString("autoDataSource"))) {
                        value = dataGenerateRule;
                    } else if ("SOURCE_SYSTEM".equals(paramMap.getString("autoDataSource"))) {
                        //组装参数结果
                        value = ParseTextUtil.parseText(dataGenerateRule, sourceDataMap);
                        //格式化日期控件
                        if ("3".equals(paramMap.get("controlType"))) {
                            //日期格式 date ，时间time，日期时间datetime  "timeShow":"yyyy年MM月dd日 hh时mm分ss秒"
                            JSONObject dateConfig = paramMap.getJSONObject("controlConfigContent");
                            String pickerType = dateConfig.getString("pickerType");
                            String timeShow = dateConfig.getString("timeShow");
                            value = DateUtil.formatDate(value, timeShow, pickerType);
                        } else if ("SOURCE_SYSTEM_List".equals(paramMap.getString("autoDataSource"))) {

                        }
                    }
                    resultData.put(paramMap.getString("templateFieldEn"), value);
                }
                // 控件类型是签名 获取执法人员签名
                if (ObjectUtil.isNotEmpty(paramMap.getString("controlType"))) {

                }
            }
        }
        return resultData;
    }

    /**
     * 根据模板字段配置信息，组装查询所需要的字段，并组装成map格式
     *
     * @param sourceFieldInfos 源字段信息
     * @param request          请求
     * @return {@link Map<String, String> }
     * @author shishengyao
     * @date 2022/02/28
     */
    private Map<String, String> getSourceDataMap(Map<String, Object> sourceFieldInfos, DocCommonHtmlRequest request) {
        Map<String, String> sourceDataMap = new HashMap<>();
        Set<String> keySet = sourceFieldInfos.keySet();
        UserDTO userInfo = UserUtil.getUserInfo();
        String orgCode = userInfo.getOrgCode();
        String deptCode = userInfo.getDeptCode();
        for (String tableName : keySet) {
            List<String> fieldList = JSONObject.parseArray(sourceFieldInfos.get(tableName).toString(), String.class);
            String fieldSql = StringUtils.join(fieldList, ",");
            String conditionSql = "";
            String whereSql = "id=" + "'" + request.getDocumentId() + "'";
            if ("sys_depart_param".equals(tableName)) {
                conditionSql = " from upcase." + tableName;
                whereSql = "org_code=" + "'" + orgCode + "' and dept_code=" + "'" + deptCode + "' and is_deleted='0'";
            }
            Map<String, Object> dataMap = new HashMap<>();
            String sqlStr = "select " + fieldSql + conditionSql + " where " + whereSql + " limit 1";
            if (StringUtils.isNotEmpty(conditionSql)) {
                dataMap = appCaseBeforeDocumentRecordMapper.executeSelectNumSql(sqlStr);
            }
            if ("sys_depart_param".equals(tableName) && ObjectUtils.isEmpty(dataMap)) {
                conditionSql = " from upcase." + tableName;
                whereSql = "org_code=" + "'" + orgCode + "' and is_deleted='0' and (dept_code is null or dept_code='')";
                sqlStr = "select " + fieldSql + conditionSql + " where " + whereSql + " limit 1";
                dataMap = appCaseBeforeDocumentRecordMapper.executeSelectNumSql(sqlStr);
            }
            //组装参数值表
            if (ObjectUtil.isNotEmpty(dataMap)) {
                for (String field : fieldList) {
                    sourceDataMap.put(tableName + "." + field, dataMap.get(field) == null ? "" : dataMap.get(field).toString());
                }
            }
        }
        return sourceDataMap;
    }

    /**
     * 获取文号
     * <p>
     * //     * @param catalogCode
     *
     * @return
     */
//    private String getDocumentNumber(String catalogCode) {
//        //“X机构”处填写制作法律文书的办案单位文号； X机构（ ）字〔 〕第 号
//        UserDTO userDTO = UserUtil.getUserInfo();
//        Map<String, String> docNumParam = caseDocumentNumberSerialMapper.getDocNumParam(catalogCode, userDTO.getOrgCode());
//        String docDeptShort = docNumParam.get("orgshortname");
//        if (StringUtils.isBlank(docDeptShort)) {
//            throw new BusinessException("机构参数配置为空");
//        }
//        //获取（ ）内的内容 如立案、移案、询通、调证、登保决、鉴聘、申避决、听通、当罚决、不罚决、行罚决、行罚缴决、强执决、代履决、强执申、电送确、终决等；
//        String numAbbreviation = docNumParam.get("docnumsimple");
//        if (StringUtils.isBlank(numAbbreviation)) {
//            throw new BusinessException("文书参数配置为空");
//        }
//        //获取年度 “〔 〕”处填写年度
//        String currentYear = "〔" + LocalDate.now().getYear() + "〕";
//        long number = getNumber(catalogCode);
//        String documentNumber = docDeptShort + numAbbreviation + currentYear + "第" + String.format("%06d", number) + "号";
//        return documentNumber;
//    }
    public String getDocumentNumber(String documentCatalogCode) {
        //“X机构”处填写制作法律文书的办案单位文号； X机构（ ）字〔 〕第 号
        //双执法主体切换
        /*List<CaseHandlePersonRecordVo> caseHandlePersonRecordVoList = caseHandlePersonRecordService.getCaseHandlePersonRecordListByCaseId(caseId);
        String handleDeptCode = caseHandlePersonRecordVoList.get(0).getHandleOrgCode();*/
        //String docDeptShort = configBusiParamDeptService.getConfigBusiParamDeptDetailByDeptCode(handleDeptCode).getDocumentDeptShort();

        //  SysDepartParam sysDepartParam = sysDepartParamService.getSysDepartParamByOrgCode(caseMainInfo.getCaseOrgCode());
        //   String docDeptShort = sysDepartParam.getOrgShortName();
        UserDTO userDTO = UserUtil.getUserInfo();
        String orgCode = userDTO.getOrgCode();
        // 获取条线信息
        List<LineTerritoryInfoVo> lineTerritoryInfoVos = sysDepartParamService.getLineInfoListByOrgCode(orgCode);
        // todo 目前只维护一个条线，暂时取第一个条线
        lineTerritoryInfoVos = lineTerritoryInfoVos.stream().filter(e -> Constant.STRING_1.equals(e.getLineCaseHandleStatusCode())).collect(Collectors.toList());
        LineTerritoryInfoVo lineTerritoryInfoVo = new LineTerritoryInfoVo();
        if (lineTerritoryInfoVos.size() > 0) {
            lineTerritoryInfoVo = lineTerritoryInfoVos.get(0);
        } else {
            throw new BusinessException("暂未配置条线信息，请联系管理员");
        }
        String lineDocNumber = lineTerritoryInfoVo.getLineDocNumber();
        //获取（ ）内的内容 如立案、移案、询通、调证、登保决、鉴聘、申避决、听通、当罚决、不罚决、行罚决、行罚缴决、强执决、代履决、强执申、电送确、终决等；
        String numAbbreviation = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(documentCatalogCode).getDocumentNumberAbbreviation();
        //获取年度 “〔 〕”处填写年度
        String curretYear = "〔" + String.valueOf(LocalDate.now().getYear()) + "〕";
        //String curretYear = "〔1990〕";
        //“第 号”处填写4位自增序号的顺序编号。从缓存原子中获取
        String documentNumberKey = "UPCASE-DOCUMENTNUMBERKEY-" + curretYear;
        // long number = redisRepository.incr(documentNumberKey);
        long number = getNumber(documentCatalogCode, orgCode, lineTerritoryInfoVo.getLineCode());
        //String documentNumber = docDeptShort + "（" + numAbbreviation + "）" + curretYear + String.format("%06d", number);
        String documentNumber = lineDocNumber + numAbbreviation + curretYear + "第" + String.format("%06d", number) + "号";
        return documentNumber;
    }

    /**
     * 获取文号
     *
     * @param busiId
     * @param documentKindCode
     * @param lineCode
     * @return
     */
    public String getDocumentNumber(String busiId, String documentKindCode, String lineCode, String lineTypeCode) {
        Map<String, Object> urlParam = new HashMap<>();
        urlParam.put("busiId", busiId);
        urlParam.put("documentKindCode", documentKindCode);
        urlParam.put("lineCode", lineCode);
        if (StrUtil.isBlank(lineTypeCode)) {
            lineTypeCode = "";
        }
        urlParam.put("lineTypeCode", lineTypeCode);
        Result result = PunishMainClientUtil.httpGet(PunishMainServicePortUriConstant.GET_DOCUMENT_NUMBER_FOR_CAR, urlParam);
        if (ObjectUtils.isEmpty(result) || HttpStatus.HTTP_OK != result.getCode() || ObjectUtils.isEmpty(result.getData())) {
            throw new BusinessException("生成文号失败，请联系管理员" + result.getMessage());
        }
        return result.getData().toString();
    }

    /**
     * 办案直通车-常用文书列表
     *
     * @return
     */
    @Override
    public List<AppDocumentListSimpleVo> getCommonlyUseDocumentList() {
        UserDTO userDTO = UserUtil.getUserInfo();
        return appCaseBeforeDocumentRecordMapper.getCommonlyUseDocumentList(userDTO.getUserId().toString(), userDTO.getOrgCode());
    }

    /**
     * 办案直通车-全部可用文书列表
     *
     * @return
     */
    @Override
    public List<AppDocumentListSimpleVo> getAllDocumentList() {
        UserDTO userDTO = UserUtil.getUserInfo();
        RelationWorkflowInfoRequest request = new RelationWorkflowInfoRequest();
        request.setApplyAreaCode(userDTO.getAreaCode());
        ConfigBusiParamMain configBusiParamMain = configBusiParamDocumentInfoService.getConfigBusiParamMain(request);
        List<AppDocumentListSimpleVo> voList = new ArrayList<>();
        //TODO 先排除送达地址确认书，等办案直通车完善后再还原
        List<AppDocumentListSimpleVo> allDocumentList = appCaseBeforeDocumentRecordMapper.getAllDocumentListByBusiParamId(configBusiParamMain.getId());

        allDocumentList.forEach(vo -> {
            voList.add(vo);
        });
        return voList;
    }

    /**
     * 办案直通车-历史文书列表
     *
     * @return
     */
    @Override
    public List<AppHisDocumentListVo> getHisDocumentList(AppHisDocQueryDto dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getLength());
        UserDTO userDTO = UserUtil.getUserInfo();
        dto.setUserId(userDTO.getUserId().toString());
        dto.setOrgCode(userDTO.getOrgCode());
        return appCaseBeforeDocumentRecordMapper.getHisDocumentList(dto);
    }

    /**
     * 签字捺印 接收 签字 指纹
     *
     * @param saveDto
     * @return
     */
    @Override
    public Map<String, Object> receiveSignFile(AppDocumentSignSaveDto saveDto) {
        //文书为送达地址确认书
        ConfigBusiParamDocumentInfo detailByDocumentCatalogCode = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(saveDto.getDocumentCatalogCode());
        String kindCode = detailByDocumentCatalogCode.getDocumentKindCode();
        CaseDocumentRecord caseDocumentRecord = caseDocumentRecordMapper.selectByPrimaryKey(saveDto.getDocumentId());
        if (DocumentKindEnum.DOC_KIND_SDDZQRS.getCode().equals(kindCode) && ObjectUtil.isNotEmpty(caseDocumentRecord)) {
            if (ObjectUtil.isNotEmpty(caseDocumentRecord.getCaseId())) {
                CaseDocumentRecordSignSaveDto dto = new CaseDocumentRecordSignSaveDto();
                BeanUtils.copyProperties(saveDto, dto);
                return caseDocumentRecordService.receiveSignFileOfCaseDoc(dto);
            }
        }

        /**
         * 接收 捺印指纹，签字字段保存， 文件重新生成带签字文书
         */
        //详情表字段保存
        AppDocumentInfoDetail appDocumentInfoDetail = appDocumentInfoDetailMapper.selectByPrimaryKey(saveDto.getDocumentId());
        if (appDocumentInfoDetail != null) {
            appDocumentInfoDetail.setSignFile(saveDto.getSignFile());
            appDocumentInfoDetail.setFingerPrint(saveDto.getFingerprint());
            appDocumentInfoDetailMapper.updateByPrimaryKeySelective(appDocumentInfoDetail);
        } else {
            throw new BusinessException("文书不存在，请检查");
        }
        // 文书表更新
        AppCaseBeforeDocumentRecordNew appCaseBeforeDocumentRecordNew = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(saveDto.getDocumentId());
        if (appCaseBeforeDocumentRecordNew == null) {
            throw new BusinessException("文书不存在，请检查");
        }
        JSONObject jsonObject = JSON.parseObject(appCaseBeforeDocumentRecordNew.getDocumentContent());
//        jsonObject.put("QM",StringUtils.isNotBlank(saveDto.getSignFile()) ? saveDto.getSignFile().replaceAll("\\s*|\r|\n|\t","") : "");
//        jsonObject.put("NY",StringUtils.isNotBlank(saveDto.getFingerprint()) ? saveDto.getFingerprint().replaceAll("\\s*|\r|\n|\t","") : "");
//         jsonObject.put("QM",StringUtils.isNotBlank(saveDto.getSignFile()) ? saveDto.getSignFile(): "");
//         jsonObject.put("NY",StringUtils.isNotBlank(saveDto.getFingerprint()) ? saveDto.getFingerprint(): "");
        // 每次都将不签字理由 移除
        jsonObject.remove("notSignReason");
        // 这里判断是否有不签字的信息
        if (StrUtil.isNotBlank(saveDto.getNotSignReason())) {
            // 设置未签字的信息
            appCaseBeforeDocumentRecordNew.setNotSignReason(saveDto.getNotSignReason());
            appCaseBeforeDocumentRecordNew.setNotSignReasonReplenish(saveDto.getNotSignReasonReplenish());
            String notSignReason = getNotReasonStr(saveDto.getNotSignReason(), saveDto.getNotSignReasonReplenish());
            jsonObject.put("notSignReason", notSignReason);
        } else {
            //签名base64优化成地址 20230522
            String base64Str = ImageUtil.overlapImage(saveDto.getSignFile(), saveDto.getFingerprint());
            // 签名的url
            String ossUrl = base64ToOssUrl(base64Str);
            if (StringUtils.isNotBlank(saveDto.getPersonnelType())) {
                // 当事人
                if (saveDto.getPersonnelType().equals(Constant.STRING_1)) {
                    jsonObject.put("signFingerprintPic", ossUrl);
                    jsonObject.put("signFingerprintDate", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年M月d日")));
                } else {
                    jsonObject.put("signFingerprintPicWitness", ossUrl);
                    jsonObject.put("signFingerprintDateWitness", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年M月d日")));
                }
            } else {
                jsonObject.put("signFingerprintPic", ossUrl);
                jsonObject.put("signFingerprintDate", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年M月d日")));
            }
        }
        appCaseBeforeDocumentRecordNew.setDocumentContent(jsonObject.toJSONString());
        // 重新生成文书
        List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = getConfigBusiParamDocumentInfos(saveDto.getDocumentCatalogCode());
        String templateCode = getTemplateCodeByDocumentCatalogCode(configBusiParamDocumentInfos, appDocumentInfoDetail.getPartyType(), null);
        HashMap<String, Object> jsonMap = new HashMap<>(64);
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            jsonMap.put(entry.getKey(), entry.getValue());
        }
        FillAndConvertToPdfRequest pdfRequest = assemblySignPdfRequest(kindCode, templateCode, jsonMap);
        UserDTO userDTO = UserUtil.getUserInfo();
        //生成标准和窄幅文书
        generateStandardAndNarrowDocumentAndFillRecord(userDTO, pdfRequest, detailByDocumentCatalogCode, appCaseBeforeDocumentRecordNew, true);
        //设置其他记录信息
        appCaseBeforeDocumentRecordNew.setSignTime(LocalDateTime.now());
        appCaseBeforeDocumentRecordNew.setDocumentSignstampedStatus(DocumentStatusEnum.CONFIRM_END.getCode());
        //修改直通车文书记录
        appCaseBeforeDocumentRecordMapper.updateByPrimaryKeySelective(appCaseBeforeDocumentRecordNew);
        Map<String, Object> resultMap = new HashMap<>(16);
        //返回
        resultMap.put("success", "true");
        resultMap.put("documentId", appCaseBeforeDocumentRecordNew.getId());
        resultMap.put("pdfSealUrl", appCaseBeforeDocumentRecordNew.getDocumentUrlAfterSign());
        return resultMap;
    }

    /**
     * 组装签名的pdf生成请求
     *
     * @param kindCode
     * @param templateCode
     * @param jsonMap
     * @return
     */
    private static FillAndConvertToPdfRequest assemblySignPdfRequest(String kindCode, String templateCode, HashMap<String, Object> jsonMap) {
        FillAndConvertToPdfRequest pdfRequest = new FillAndConvertToPdfRequest();
        if (DocumentKindEnum.DOC_KIND_DK2LJDLXJDS.getCode().equals(kindCode) || DocumentKindEnum.DOC_KIND_DK2XZQZZXXCBL.getCode().equals(kindCode)) {
            //立即代履行决定书和行政强制执行现场笔录标准模板
            pdfRequest.setTemplateType(DocumentTemplateKindEnum.STANDARD_TEMPLATE.getCode());
        }
        pdfRequest.setTemplateCode(templateCode);
        pdfRequest.setParamMap(jsonMap);
        return pdfRequest;
    }

    /**
     * 拼接未签字信息
     */
    public String getNotReasonStr(String notSignReason, String notSignReasonReplenish) {
        StringBuilder notSignReasonBuilder = new StringBuilder("当事人未签字，原因是：");
        notSignReasonBuilder.append(NotSignReasonEnum.getValueByCode(notSignReason));
        if (StrUtil.isNotBlank(notSignReasonReplenish)) {
            notSignReasonBuilder.append(",");
            notSignReasonBuilder.append(notSignReasonReplenish);
        }
        return notSignReasonBuilder.toString();
    }

    /**
     * 根据文书目录编码查询关联文书
     *
     * @param request
     * @return
     */
    @Override
    public List<AppRelationDocumentListVo> getRelationDocumentListByCatalogCode(DocCommonHtmlRequest request) {
        List<AppRelationDocumentListVo> vos = new ArrayList<>();
        ConfigBusiParamDocumentInfo paramDocumentInfo = new ConfigBusiParamDocumentInfo();
        paramDocumentInfo.setDocumentCatalogCode(request.getDocumentCatalogCode());
        List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = configBusiParamDocumentInfoMapper.select(paramDocumentInfo);
        if (!configBusiParamDocumentInfos.isEmpty() && StringUtils.isNotBlank(configBusiParamDocumentInfos.get(0).getRelationDocumentCatalogCode())) {
            String[] documentCatalogCodes = configBusiParamDocumentInfos.get(0).getRelationDocumentCatalogCode().split(",");
            Example example = new Example(AppCaseBeforeDocumentRecordNew.class);
            example.createCriteria().andIn("documentCatalogCode", Arrays.asList(documentCatalogCodes))
                    .andEqualTo("createUserId", UserUtil.getUserInfo().getUserId().toString()).andIsNotNull("documentUrlAfterSign");
            List<AppCaseBeforeDocumentRecordNew> appCaseBeforeDocumentRecordNews = appCaseBeforeDocumentRecordMapper.selectByExample(example);
            for (AppCaseBeforeDocumentRecordNew record : appCaseBeforeDocumentRecordNews) {

                AppRelationDocumentListVo vo = new AppRelationDocumentListVo();
                vo.setDocumentId(record.getId());
                vo.setDocumentCatalogCode(record.getDocumentCatalogCode());
                vo.setDocUrl(record.getDocumentUrlAfterSeal());
                vo.setDocumentName(record.getDocumentName());
                vo.setDocumentNumber(record.getDocumentNumber());
                vo.setDocumentConfirmDate(record.getSignTime().toLocalDate().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
                vos.add(vo);
            }
        }
        return vos;
    }

    /**
     * 移动端办案直通车-文书id查询关联文书详情
     *
     * @param request
     * @return
     */
    @Override
    public AppRelationDocumentListVo getRelationDocumentDetailInfo(DocumentDetailQueryDto request) {
        AppRelationDocumentListVo vo = new AppRelationDocumentListVo();
        AppDocumentInfoDetail detail = appDocumentInfoDetailMapper.selectByPrimaryKey(request.getDocumentId());
        if (detail != null) {
            BeanUtils.copyProperties(detail, vo);
        }
        AppCaseBeforeDocumentRecordNew record = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(request.getDocumentId());
        if (record != null) {
            BeanUtils.copyProperties(record, vo);
        }
        Example example = new Example(AppDocumentRelatedGoods.class);
        example.createCriteria().andEqualTo("documentId", request.getDocumentId());
        List<AppDocumentRelatedGoods> goodsList = appDocumentRelatedGoodsMapper.selectByExample(example);
        if (!goodsList.isEmpty()) {
            vo.setGoodsList(goodsList);
        }
        return vo;
    }

    @Override
    public JSONArray getEntList(EntQueryDto dto) {
        try {
            Map<String, Object> map = new HashMap<>(4);
            map.put("tyxydm", dto.getTyxydm());
            map.put("frmc", dto.getFrmc());
            String url = "http://59.202.52.139:8082/frk/api/getqyjbxx";
            String rsp = HttpUtil.createGet(url).form(map).execute().body();
            JSONObject jsonObject = JSONObject.parseObject(rsp);
            String tz = "00";
            if (tz.equals(jsonObject.getString(CODE))) {
                JSONArray array = jsonObject.getJSONArray("result");
                return array;
            }
        } catch (Exception e) {
            logger.error("查询企业信息外部接口异常:", e);
        }
        return null;
    }

    /**
     * 获取执法人员签名
     *
     * @param userId
     * @return
     */
    @Override
    public String getHandleSignData(String userId) {
        try {
            Map<String, Object> paramMap = Collections.singletonMap("userId", userId);
            Result result = PunishMainClientUtil.httpGet(PunishMainServicePortUriConstant.GET_HANDLE_SIGN, paramMap);
            String signData = result.getData().toString();
            return signData;
        } catch (Exception e) {
            logger.error("获取执法人员签名失败！", e);
            if ("true".equals(isCheckHandleSign)) {
                throw new BusinessException("获取用户签名信息异常！请稍后再试");
            } else {
                return "";
            }
        }
    }

    /**
     * 根据配置更新相关数据
     *
     * @param saveDto
     * @return
     * @author liyafeng
     * @date 2022/3/1
     */
    private void operateBusiTableByDocumentCatalogCode(AppDocumentCommonSaveDto saveDto) {
        List<BusiTableOperateVo> busiTableOperateVoList = configBusiParamDocumentColumnMapper.selectTableNameListByDocumentCatalogCode(saveDto.getDocumentCatalogCode());
        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(saveDto.getDocumentCatalogCode());
        // todo app端没有caseid 目前只处理送达地址确认书，app端没有caseid
        if (null != busiTableOperateVoList && busiTableOperateVoList.size() > 0 && Constant.STRING_KIND_CODE_SDDZQRS.equals(configBusiParamDocumentInfo.getDocumentKindCode())) {
            for (BusiTableOperateVo busiTableOperateVo : busiTableOperateVoList) {
                Example example = new Example(ConfigBusiParamDocumentColumn.class);
                example.createCriteria().andEqualTo("documentCatalogCode", saveDto.getDocumentCatalogCode()).andEqualTo("busiTableNameEn", busiTableOperateVo.getBusiTableNameEn()).andEqualTo("busiOperateType", busiTableOperateVo.getBusiOperateType());
                List<ConfigBusiParamDocumentColumn> configBusiParamDocumentColumnList = configBusiParamDocumentColumnMapper.selectByExample(example);
                if ("U".equals(busiTableOperateVo.getBusiOperateType())) {
                    updateBusiTable(busiTableOperateVo, busiTableOperateVoList, saveDto, configBusiParamDocumentColumnList);
                }
                if ("I,U".equals(busiTableOperateVo.getBusiOperateType())) {
                    //先判断是否存在
                    // String selectSql = "select count(1) from upcase." + busiTableOperateVo.getBusiTableNameEn() + " where case_id='" + saveDto.getCaseId() + "'";
                    String selectSql = "select count(1) from upcase." + busiTableOperateVo.getBusiTableNameEn() + " where 1=1 ";
                    String partyIdentityType = "";
                    String partyIdentityCode = "";
                    if (Constant.STRING_KIND_CODE_SDDZQRS.equals(configBusiParamDocumentInfo.getDocumentKindCode())) {
                        if (ObjectUtil.isNotEmpty(saveDto.getUnicode())) {
                            partyIdentityCode = saveDto.getUnicode();
                        } else if (ObjectUtil.isNotEmpty(saveDto.getPersonCertNo())) {
                            partyIdentityType = saveDto.getPersonCertType();
                            partyIdentityCode = saveDto.getPersonCertNo();
                        }
                        selectSql = selectSql.concat(" and party_identity_type = '" + saveDto.getPersonCertType() + "'" + "and party_identity_code = '" + saveDto.getPersonCertType() + "'");
                    }


                    int num = configBusiParamDocumentColumnMapper.executeSelectNumSql(selectSql);
                    if (num > 0) {
                        //存在则更新
                        updateBusiTable(busiTableOperateVo, busiTableOperateVoList, saveDto, configBusiParamDocumentColumnList);

                    } else {
                        //不存在则插入
                        Map<String, String> insertMap = new HashMap<>();
                        //组装map
                        for (ConfigBusiParamDocumentColumn configBusiParamDocumentColumn : configBusiParamDocumentColumnList) {
                            if ("id".equals(configBusiParamDocumentColumn.getBusiOperateCondition())) {
                                insertMap.put(configBusiParamDocumentColumn.getBusiColumnEn(), StringUtils.uuid());
                                continue;
                            }
                            if ("case_id".equals(configBusiParamDocumentColumn.getBusiOperateCondition())) {
                                insertMap.put(configBusiParamDocumentColumn.getBusiColumnEn(), saveDto.getCaseId());
                                continue;
                            }
                            if ("document_catalog_code".equals(configBusiParamDocumentColumn.getBusiOperateCondition())) {
                                insertMap.put(configBusiParamDocumentColumn.getBusiColumnEn(), saveDto.getDocumentCatalogCode());
                                continue;
                            }
                            if ("create_time".equals(configBusiParamDocumentColumn.getBusiOperateCondition())) {
                                insertMap.put(configBusiParamDocumentColumn.getBusiColumnEn(), DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
                                continue;
                            }
                            //---送达方式及地址确认书使用start---
                            if ("party_identity_code".equals(configBusiParamDocumentColumn.getBusiOperateCondition())) {
                                insertMap.put(configBusiParamDocumentColumn.getBusiColumnEn(), partyIdentityCode);
                                continue;
                            }
                            if ("party_identity_type".equals(configBusiParamDocumentColumn.getBusiOperateCondition())) {
                                insertMap.put(configBusiParamDocumentColumn.getBusiColumnEn(), partyIdentityType);
                                continue;
                            }
                            /*if ("status".equals(configBusiParamDocumentColumn.getBusiOperateCondition())) {
                                insertMap.put(configBusiParamDocumentColumn.getBusiColumnEn(), null);//默认设置为空，签字确认后修改为1
                                continue;
                            }*/
                            //---送达方式及地址确认书使用end---

                            String columnValue = "";
                            try {
                                //columnValue = saveDto.getDataMap().get(configBusiParamDocumentColumn.getDocumentTemplateFieldEn()).toString();
                                columnValue = MapUtils.getString(saveDto.getDataMap(), configBusiParamDocumentColumn.getDocumentTemplateFieldEn(), "");
                            } catch (Exception e) {
                                throw new com.icinfo.cloud.provider.common.exception.BusinessException(configBusiParamDocumentColumn.getDocumentTemplateFieldCn() + "为空");
                            }
                            insertMap.put(configBusiParamDocumentColumn.getBusiColumnEn(), columnValue);
                        }
                        //生成INSERT INTO table(field1,field2) 部分
                        StringBuffer sbField = new StringBuffer();
                        //生成VALUES('value1','value2') 部分
                        StringBuffer sbValue = new StringBuffer();
                        sbField.append("INSERT INTO  upcase." + busiTableOperateVo.getBusiTableNameEn() + "(");
                        for (Map.Entry<String, String> entry : insertMap.entrySet()) {
                            String mapKey = entry.getKey();
                            String mapValue = entry.getValue();
                            sbField.append(mapKey + ",");
                            sbValue.append("'" + mapValue + "',");
                        }
                        sbField = sbField.deleteCharAt(sbField.length() - 1);
                        sbValue = sbValue.deleteCharAt(sbValue.length() - 1);
                        String insertSql = sbField.toString() + ") VALUES(" + sbValue.toString() + ")";
                        configBusiParamDocumentColumnMapper.executeInsertSql(insertSql);
                    }


                }
            }
        }
    }

    /**
     * 更新操作
     *
     * @param busiTableOperateVo
     * @param busiTableOperateVoList
     * @param saveDto
     * @param configBusiParamDocumentColumnList
     * @return
     * @author liyafeng
     * @date 2022/3/11
     */
    private void updateBusiTable(BusiTableOperateVo busiTableOperateVo, List<BusiTableOperateVo> busiTableOperateVoList, AppDocumentCommonSaveDto saveDto, List<ConfigBusiParamDocumentColumn> configBusiParamDocumentColumnList) {
        String tableName = busiTableOperateVo.getBusiTableNameEn();
        String caseId = saveDto.getCaseId();
        String setSql = "";
        for (ConfigBusiParamDocumentColumn configBusiParamDocumentColumn : configBusiParamDocumentColumnList) {
            //BusiOperateCondition 不为空 此字段不更新
            if (StringUtils.isNotBlank(configBusiParamDocumentColumn.getBusiOperateCondition())) {
                continue;
            }
            String columnValue = "";
            try {
                columnValue = saveDto.getDataMap().get(configBusiParamDocumentColumn.getDocumentTemplateFieldEn()).toString();
            } catch (Exception e) {
                //前端没有传key值，此字段不更新
                if (saveDto.getDataMap().get(configBusiParamDocumentColumn.getDocumentTemplateFieldEn()) == null)
                    continue;

                throw new com.icinfo.cloud.provider.common.exception.BusinessException(configBusiParamDocumentColumn.getDocumentTemplateFieldCn() + "为空");
            }
            if (StringUtils.isBlank(setSql)) {
                setSql = configBusiParamDocumentColumn.getBusiColumnEn() + "='" + columnValue + "'";
            } else {
                setSql = setSql + "," + configBusiParamDocumentColumn.getBusiColumnEn() + "='" + columnValue + "'";
            }
        }
        String updateSql = "update upcase." + tableName + " set " + setSql + " where " + " 1=1'";

        ConfigBusiParamDocumentInfo configBusiParamDocumentInfo = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(saveDto.getDocumentCatalogCode());
        if (Constant.STRING_KIND_CODE_SDDZQRS.equals(configBusiParamDocumentInfo.getDocumentKindCode())) {
            String partyIdentityType = "";
            String partyIdentityCode = "";
            if (ObjectUtil.isNotEmpty(saveDto.getUnicode())) {
                partyIdentityCode = saveDto.getUnicode();
            } else if (ObjectUtil.isNotEmpty(saveDto.getPersonCertNo())) {
                partyIdentityType = saveDto.getPersonCertType();
                partyIdentityCode = saveDto.getPersonCertNo();
            }
            updateSql = updateSql.concat(" and party_identity_type = '" + saveDto.getPersonCertType() + "'" + "and party_identity_code = '" + saveDto.getPersonCertType() + "'");
        }
        configBusiParamDocumentColumnMapper.executeUpdateSql(updateSql);
    }

    /**
     * 从文书管理 获取模板详情
     *
     * @param templateCode 模板代码
     * @return {@link Map<String, Object> }
     * @author shishengyao
     * @date 2022/04/29
     */
    public Map<String, Object> getTemplateDetailConfig(String templateCode) {
        //根据文书目录编码获取模板code
        //从文书管理 获取模板code
        Map<String, Object> paramsMap = new HashMap<>();
        Map<String, String> headers = HeaderUtil.headerInfo();
        Map<String, Object> paramMap = new HashMap<>(2);
        paramMap.put("templateCode", templateCode);
        paramMap.put("templateType", "narrow");
        String result = HttpUtil.createPost(url.concat(templateDetail)).addHeaders(headers).body(JSON.toJSONString(paramMap)).contentType("application/json").execute().body();
        if (StringUtils.isNotBlank(result)) {
            JSONObject jsonObject = JSONObject.parseObject(result);
            if ("200".equals(jsonObject.get("code").toString())) {
                logger.info("getTemplateDetailConfig文书获取成功，result:" + result);
                JSONObject data = JSON.parseObject(jsonObject.get("data").toString());
                //获取返回的html内容
                paramsMap.put("htmlContent", data.getString("standardFormTemplate"));
                paramsMap.put("templateFieldConfigs", data.getString("templateFieldConfigs"));
                paramsMap.put("sourceFieldInfos", data.getString("sourceFieldInfoMap"));
            } else {
                logger.info("调用失败，result:" + result);
                throw new com.icinfo.cloud.provider.common.exception.BusinessException(templateCode + "对应的文书不存在");
            }
        } else {
            throw new com.icinfo.cloud.provider.common.exception.BusinessException("文书服务网络异常！");
        }
        return paramsMap;
    }

    /**
     * 获得序列号
     *
     * @param documentCatalogCode
     * @return
     */
//    private Long getNumber(String documentCatalogCode) {
//        UserDTO userDTO = UserUtil.getUserInfo();
//        // 分布式锁
//        CaseDocumentNumberSerial param = new CaseDocumentNumberSerialDto();
//        param.setAreaCode(userDTO.getOrgCode());
//        param.setDocumentCatalogCode(documentCatalogCode);
//        List<CaseDocumentNumberSerial> caseDocumentNumberSerial = caseDocumentNumberSerialMapper.select(param);
//        if (caseDocumentNumberSerial.isEmpty()) {
//            //新增文书序列
//            CaseDocumentNumberSerial newCaseSerial = new CaseDocumentNumberSerial();
//            newCaseSerial.setSerial(1L);
//            newCaseSerial.setId(com.icinfo.framework.tools.utils.StringUtils.uuid());
//            newCaseSerial.setDocumentCatalogCode(documentCatalogCode);
//            newCaseSerial.setAreaCode(userDTO.getOrgCode());
//            caseDocumentNumberSerialMapper.insert(newCaseSerial);
//            return 1L;
//        }
//        // 更新逻辑
//        CaseDocumentNumberSerial upDateSerial = caseDocumentNumberSerialMapper.selectForLock(documentCatalogCode, userDTO.getOrgCode());
//        upDateSerial.setSerial(upDateSerial.getSerial() + 1);
//        upDateSerial.setAreaCode(userDTO.getOrgCode());
//        caseDocumentNumberSerialMapper.updateByPrimaryKeySelective(upDateSerial);
//        return upDateSerial.getSerial();
//    }
    public Long getNumber(String documentCatalogCode, String caseOrgCode, String lineCode) {
        CaseDocumentNumberSerial param = new CaseDocumentNumberSerialDto();
        param.setDocumentCatalogCode(documentCatalogCode);
        param.setAreaCode(caseOrgCode);
        param.setLineCode(lineCode);
        List<CaseDocumentNumberSerial> caseDocumentNumberSerial = caseDocumentNumberSerialMapper.select(param);
        if (caseDocumentNumberSerial.isEmpty()) {
            //新增文书序列
            CaseDocumentNumberSerial newCaseSerial = new CaseDocumentNumberSerial();
            newCaseSerial.setSerial(1L);
            newCaseSerial.setId(StringUtils.uuid());
            newCaseSerial.setDocumentCatalogCode(documentCatalogCode);
            newCaseSerial.setAreaCode(caseOrgCode);
            newCaseSerial.setLineCode(lineCode);
            caseDocumentNumberSerialMapper.insert(newCaseSerial);
            return 1L;
        }
        // 更新逻辑
        CaseDocumentNumberSerial upDateSerial = caseDocumentNumberSerialMapper.selectForLock(documentCatalogCode, caseOrgCode, lineCode);
        upDateSerial.setSerial(upDateSerial.getSerial() + 1);
        upDateSerial.setAreaCode(caseOrgCode);
        upDateSerial.setLineCode(lineCode);
        caseDocumentNumberSerialMapper.updateByPrimaryKeySelective(upDateSerial);
        return upDateSerial.getSerial();
    }

    /**
     * 描述： 获取上一次询问通知书地址
     *
     * @return {@link String}
     * @author: zhengqiang
     * @date: 2022/8/31
     **/
    @Override
    public String getHisNoticeOfEnquiryAddress() {
        UserDTO userDTO = UserUtil.getUserInfo();
        String content = appCaseBeforeDocumentRecordMapper.getHisNoticeOfEnquiryAddress(userDTO.getUserId().toString(), userDTO.getOrgCode());
        JSONObject jsonObject = JSONObject.parseObject(content);
        String hisNoticeOfEnquiryAddress = jsonObject.getString("xwtzs_xwdz");
        return hisNoticeOfEnquiryAddress;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppDocumentCommonModifyVo modifyDocumentInfo(AppDocumentCommonSaveDto saveDto) {
        UserDTO userInfo = UserUtil.getUserInfo();
        if (null == userInfo) {
            throw new BusinessException("登录失效");
        }
        String documentId = saveDto.getDocumentId();
        AppCaseBeforeDocumentRecordNew oldDocumentRecord = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(documentId);
        if (ObjectUtil.isEmpty(oldDocumentRecord)) {
            throw new BusinessException("修改的文书id：{" + documentId + "}不存在");
        }
        if (!oldDocumentRecord.getDocumentCatalogCode().equals(saveDto.getDocumentCatalogCode())) {
            throw new BusinessException("不可将文书修改成其他种类");
        }
        // 校验关联任务是否允许修改
        verifyAssociatedTask(documentId, OpTypeEnum.MODIFY.getErrorMessage());

        // 当事人信息校验
        checkParties(saveDto);
        // 插入文书历史表
        insertDocumentRecordHis(userInfo, oldDocumentRecord, OpTypeEnum.MODIFY.getCode());

        //处理变更文书记录表
        AppDocumentCommonModifyVo resultVo = dealModifyAppCaseBeforeDocumentRecords(saveDto, documentId, userInfo, oldDocumentRecord);
        //处理变更文书内容表
        dealModifyAppDocumentInfoDetail(saveDto, documentId, userInfo);
        //处理变更文书关联物品表
        dealModifyRelatedGoods(saveDto, documentId);
        //处理变更文书执法人员信息处理
        dealModifyDocumentHandlePersonRecord(saveDto, documentId);
        //若需要更新则根据配置更新相关数据
        operateBusiTableByDocumentCatalogCode(saveDto);
        return resultVo;
    }

    /**
     * 插入文书历史记录表
     *
     * @param userInfo
     * @param oldDocumentRecord
     * @param OpType
     */
    private void insertDocumentRecordHis(UserDTO userInfo, AppCaseBeforeDocumentRecordNew oldDocumentRecord, String OpType) {
        //1、将数据加入历史表
        AppCaseBeforeDocumentRecordHis insertRecordHis = new AppCaseBeforeDocumentRecordHis();
        BeanUtils.copyProperties(oldDocumentRecord, insertRecordHis);
        insertRecordHis.setId(BaseUtil.createUid());
        insertRecordHis.setRecordId(oldDocumentRecord.getId());
        insertRecordHis.setOp(OpType);
        insertRecordHis.setHisCreateTime(LocalDateTime.now());
        insertRecordHis.setHisCreateUserId(userInfo.getUserId() + "");
        appCaseBeforeDocumentRecordHisMapper.insertSelective(insertRecordHis);
    }

    @Override
    public AppCaseBeforeDocumentDetailVo getAppDocumentDetailByDocumentId(String documentId) {
        AppCaseBeforeDocumentDetailVo vo = new AppCaseBeforeDocumentDetailVo();
        //填充直通车文书记录信息
        fillDocumentRecord(documentId, vo);
        //填充直通车文书详情信息
        fillDocumentInfoDetail(documentId, vo);
        //填充历史执法人员信息
        fillHandlePersonInfo(documentId, vo);
        //填充直通车短信发送记录
        fillDocumentSendRecord(documentId, vo);
        return vo;
    }

    /**
     * 填充直通车详情信息
     *
     * @param documentId 直通车文书id
     * @param vo         直通车文书详情信息
     */
    private void fillDocumentInfoDetail(String documentId, AppCaseBeforeDocumentDetailVo vo) {
        AppDocumentInfoDetail appDocumentInfoDetail = appDocumentInfoDetailMapper.selectByPrimaryKey(documentId);
        BeanUtils.copyProperties(appDocumentInfoDetail, vo);
        vo.setDocumentObjectType(appDocumentInfoDetail.getPartyType());
        vo.setDocumentCatalogCode(appDocumentInfoDetail.getDocumentCatalogCode());
        // 查询直通车关联任务信息
        if (StrUtil.isNotEmpty(appDocumentInfoDetail.getAssociatedInfo())) {
            List<AssociatedTaskVo> associatedTaskVos = JSON.parseArray(appDocumentInfoDetail.getAssociatedInfo(), AssociatedTaskVo.class);
            vo.setAssociatedInfo(associatedTaskVos);
        } else {
            vo.setAssociatedInfo(Collections.emptyList());
        }
    }

    /**
     * 填充直通车文书记录信息
     *
     * @param documentId 直通车文书id
     * @param vo         直通车详情信息
     */
    private void fillDocumentRecord(String documentId, AppCaseBeforeDocumentDetailVo vo) {
        AppCaseBeforeDocumentRecordNew documentRecord = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(documentId);
        if (ObjectUtil.isEmpty(documentRecord)) {
            throw new BusinessException("查询的文书{" + documentId + "}不存在");
        }
        Map<String, Object> dataMap = JSON.parseObject(documentRecord.getDocumentContent());
        vo.setDataMap(dataMap);
        vo.setDocumentId(documentRecord.getId());
        vo.setDocumentCreateTime(documentRecord.getDocumentCreateTime());
        vo.setDocumentUrl(documentRecord.getDocumentUrl());
        vo.setDocumentUrlAfterSeal(documentRecord.getDocumentUrlAfterSeal());
        vo.setDocumentUrlAfterSign(documentRecord.getDocumentUrlAfterSign());
        vo.setDocumentStandardUrl(documentRecord.getDocumentStandardUrl());
        vo.setDocumentStandardUrlAfterSeal(documentRecord.getDocumentStandardUrlAfterSeal());
        vo.setDocumentStandardUrlAfterSign(documentRecord.getDocumentStandardUrlAfterSign());
        vo.setDocumentStatus(DocumentStatusEnum.CONFIRM_END.getCode().equals(documentRecord.getDocumentSignstampedStatus()) ? "已确认" : "待确认");
        ZtcSourceTypeEnum sourceTypeEnum = ZtcSourceTypeEnum.getZtcSourceTypeEnumByCode(documentRecord.getSourceType());
        vo.setSourceType(sourceTypeEnum);
        if (ZtcSourceTypeEnum.CHECK_OBJECT.equals(sourceTypeEnum)) {
            vo.setSourceContent(JSONObject.parseObject(documentRecord.getSourceContent(), ZtcCheckObjectContentDto.class));
        }
    }

    /**
     * 填充历史执法人员信息
     *
     * @param documentId 文书id
     * @param vo         文书详情对象
     */
    private void fillHandlePersonInfo(String documentId, AppCaseBeforeDocumentDetailVo vo) {
        List<AppDocumentHandlePersonRecord> handlePersonRecordList = appDocumentHandlePersonRecordService.getAppDocumentHandlePersonByDocumentId(documentId);
        for (AppDocumentHandlePersonRecord handlePersonRecord : handlePersonRecordList) {
            if (HandlePersonTypeEnum.MAIN.getCode().equals(handlePersonRecord.getHandlePersonType())) {
                vo.setMainHandleDeptCode(handlePersonRecord.getHandleDeptCode());
                vo.setMainHandleDeptName(handlePersonRecord.getHandleDeptName());
                vo.setMainHandleDingId(handlePersonRecord.getDingId());
                vo.setMainHandleOrgCode(handlePersonRecord.getHandleOrgCode());
                vo.setMainHandleOrgName(handlePersonRecord.getHandleOrgName());
                vo.setMainHandleTel(handlePersonRecord.getHandlePersonTel());
                vo.setMainHandleUser(handlePersonRecord.getHandlePersonName());
                vo.setMainHandleUserId(handlePersonRecord.getHandlePersonId());
            } else if (HandlePersonTypeEnum.ASSIST.getCode().equals(handlePersonRecord.getHandlePersonType())) {
                vo.setAssistHandleDeptCode(handlePersonRecord.getHandleDeptCode());
                vo.setAssistHandleDeptName(handlePersonRecord.getHandleDeptName());
                vo.setAssistHandleDingId(handlePersonRecord.getDingId());
                vo.setAssistHandleOrgCode(handlePersonRecord.getHandleOrgCode());
                vo.setAssistHandleOrgName(handlePersonRecord.getHandleOrgName());
                vo.setAssistHandleTel(handlePersonRecord.getHandlePersonTel());
                vo.setAssistHandleUser(handlePersonRecord.getHandlePersonName());
                vo.setAssistHandleUserId(handlePersonRecord.getHandlePersonId());
            }
        }
    }

    /**
     * 填充直通车短信发送记录
     *
     * @param documentId 文书
     * @param vo         文书详情对象
     */
    private void fillDocumentSendRecord(String documentId, AppCaseBeforeDocumentDetailVo vo) {
        Example example = new Example(AppDocumentSendRecord.class);
        example.createCriteria().andEqualTo("documentId", documentId);
        List<AppDocumentSendRecord> appDocumentSendRecords = appDocumentSendRecordMapper.selectByExample(example);
        if (ObjectUtil.isEmpty(appDocumentSendRecords)) {
            vo.setSendNotifyRecordList(Collections.emptyList());
            return;
        }
        //转换短信对象，填入相应对象中
        vo.setSendNotifyRecordList(appDocumentSendRecords.stream().map(appDocumentSendRecord -> {
            AppCaseSendNotifyRecordVo appCaseSendNotifyRecordVo = new AppCaseSendNotifyRecordVo();
            BeanUtils.copyProperties(appDocumentSendRecord, appCaseSendNotifyRecordVo);
            return appCaseSendNotifyRecordVo;
        }).collect(Collectors.toList()));
    }

    /**
     * 描述：处理文书记录表
     *
     * @param saveDto    保存dto
     * @param documentId 文档id
     * @author shishengyao
     * @date 2023/02/21
     */
    private AppDocumentCommonModifyVo dealModifyAppCaseBeforeDocumentRecords(AppDocumentCommonSaveDto saveDto, String documentId, UserDTO userDTO, AppCaseBeforeDocumentRecordNew oldDocumentRecord) {

        //送达地址确认书
        ConfigBusiParamDocumentInfo detailByDocumentCatalogCode = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(saveDto.getDocumentCatalogCode());
        String kindCode = detailByDocumentCatalogCode.getDocumentKindCode();
        if (DocumentKindEnum.DOC_KIND_SDDZQRS.getCode().equals(kindCode) && ObjectUtil.isNotEmpty(saveDto.getCaseId())) {
            // todo 案件关联送达地址确认书目前不支持修改
            throw new BusinessException("案件关联送达地址确认书暂不支持修改");
        }

        /**
         * ========================================数据处理======================================================================
         */
        //根据文书目录编码获取模板code
        List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = getConfigBusiParamDocumentInfos(saveDto.getDocumentCatalogCode());
        String templateCode = getTemplateCodeByDocumentCatalogCode(configBusiParamDocumentInfos, saveDto.getDocumentObjectType(), null);
        //获取当事人名称
        String partyName = getPartyName(saveDto);
        // 构建基础的文书参数信息
        HashMap<String, Object> paramMap = assemblyBaseParamMap(saveDto, userDTO, partyName);
        //清空文书参数已签字的信息
        clearSignInfo(paramMap);
        //从历史文书记录中设置文书号
        paramMap.put("documentNumber", oldDocumentRecord.getDocumentNumber());
        //生成不带签章带签名原始文书
        //生成未签章文书
        FillAndConvertToPdfRequest pdfRequest = assemblePdfRequest(templateCode, kindCode, paramMap);
        //构建待修改文书记录信息
        AppCaseBeforeDocumentRecordNew caseDocumentRecord = new AppCaseBeforeDocumentRecordNew();
        BeanUtils.copyProperties(oldDocumentRecord, caseDocumentRecord);
        //生成宽幅，窄幅文书
        //生成文书并填充文书记录数据
        generateStandardAndNarrowDocumentAndFillRecord(userDTO, pdfRequest, detailByDocumentCatalogCode, caseDocumentRecord, false);
        /*---*/
        //清空已签字的文书信息
        caseDocumentRecord.setDocumentUrlAfterSign(null);
        caseDocumentRecord.setDocumentStandardUrlAfterSign(null);
        caseDocumentRecord.setDocumentUrlPrint(null);
        // 文书记录表数据更新
        caseDocumentRecord.setCreateTime(LocalDateTime.now());
        caseDocumentRecord.setId(documentId);
        //仅直通车存储窄幅文书参数
        caseDocumentRecord.setDocumentSignstampedStatus(DocumentStatusEnum.WAIT_TO_CONFIRM.getCode());
        caseDocumentRecord.setUpdator(userDTO.getUserId().toString());
        caseDocumentRecord.setUpdateTime(LocalDateTime.now());
        caseDocumentRecord.setOrgCode(userDTO.getOrgCode());
        caseDocumentRecord.setOrgName(userDTO.getOrgName());
        caseDocumentRecord.setDeptCode(userDTO.getDeptCode());
        caseDocumentRecord.setDocumentCatalogCode(oldDocumentRecord.getDocumentCatalogCode());
        caseDocumentRecord.setDocumentTittle(partyName + "的" + oldDocumentRecord.getDocumentName());
        if (appCaseBeforeDocumentRecordMapper.updateByPrimaryKey(caseDocumentRecord) != 1) {
            throw new BusinessException("文书提交保存失败");
        }
        return buildModifyDocumentResult(documentId, caseDocumentRecord, configBusiParamDocumentInfos);
    }

    /**
     * 清空已签字的信息
     *
     * @param paramMap 文书参数
     */
    private static void clearSignInfo(HashMap<String, Object> paramMap) {
        paramMap.remove("signFingerprintPic");
        paramMap.remove("signFingerprintDate");
        paramMap.remove("signFingerprintPicWitness");
        paramMap.remove("signFingerprintDateWitness");
        paramMap.remove("notSignReason");
    }

    /**
     * 构建文书重置响应结果
     *
     * @param documentId                   文书id
     * @param caseDocumentRecord           文书记录
     * @param configBusiParamDocumentInfos 文书参数配置
     * @return
     */
    private static AppDocumentCommonModifyVo buildModifyDocumentResult(String documentId, AppCaseBeforeDocumentRecordNew caseDocumentRecord, List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos) {
        AppDocumentCommonModifyVo resultVo = new AppDocumentCommonModifyVo();
        resultVo.setDocId(documentId);
        resultVo.setPdfSealUrl(caseDocumentRecord.getDocumentUrlAfterSeal());
        resultVo.setUnSealPdfUrl(caseDocumentRecord.getDocumentUrl());
        resultVo.setSuccess("true");
        resultVo.setShowEditButtonType(configBusiParamDocumentInfos.get(0).getIsAllowEdit());
        return resultVo;
    }

    /**
     * 构建基础的文书参数信息
     *
     * @param saveDto
     * @param userDTO
     * @param partyName
     * @return
     */
    private HashMap<String, Object> assemblyBaseParamMap(AppDocumentCommonSaveDto saveDto, UserDTO userDTO, String partyName) {
        HashMap<String, Object> paramMap = addHandlerSigns(saveDto);
        //获取历史文号
        paramMap.put("partyName", partyName);
        paramMap.put("partyName1", partyName);
        paramMap.put("partyName2", partyName);
        paramMap.put("partyName3", partyName);
        paramMap.put("partyName4", partyName);
//        paramMap.put("orgStandardNameSeal", userDTO.getOrgName());
//        paramMap.put("orgStandardName", userDTO.getOrgName());
        String sealDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年M月d日"));
        paramMap.put("sealDate", sealDate);
        paramMap.put("entAddress", saveDto.getEntAddress());
        if (!ObjectUtils.isEmpty(userDTO)) {
            paramMap.put("noteTaker", userDTO.getRealName()); // 记录人，当前登录人
        }
        paramMap.put("orgCode", userDTO.getOrgCode());
        paramMap.put("deptCode", userDTO.getDeptCode());
        //生成签章pdf上传oss
        String sealPreviewInfo = docCommonOperateService.getSealPreviewInfo(userDTO.getOrgName(), sealDate,
                userDTO.getOrgCode(), userDTO.getDeptCode());
        //将生成的签章图片存储，用于后续打印使用
        paramMap.put("sealPic", sealPreviewInfo);
        return paramMap;
    }

    /**
     * 生成文书并填充文书记录数据，根据文书记录中的文书号生成文书pdf
     *
     * @param userInfo                    用户信息
     * @param pdfRequest                  文书参数
     * @param configBusiParamDocumentInfo 文书配置
     * @param caseDocumentRecord          文书记录数据
     * @param afterSign                   是否签字
     */
    private void generateDocumentAndFillRecord(UserDTO userInfo, FillAndConvertToPdfRequest pdfRequest,
                                               ConfigBusiParamDocumentInfo configBusiParamDocumentInfo,
                                               AppCaseBeforeDocumentRecordNew caseDocumentRecord,
                                               Boolean afterSign) {
        //转换narrow参数到standard参数，因为pdfRequest里存放的是narrow参数，若需要生成标准文书时需要转换
        pdfRequest = convertNarrowToStandardParam(configBusiParamDocumentInfo, pdfRequest);
        Map<String, Object> paramMap = pdfRequest.getParamMap();
        //是否需要办案部门签章
        boolean isDeptSign = Constant.STRING_1.equals(configBusiParamDocumentInfo.getIsDeptSign());
        // 生成文书
        Map<String, String> unSealPdfUrlResult = getConvertedPdfUrl(pdfRequest);
        // 获取参数map，因为前置业务中pdfRequest里存放的为窄幅文书的文书参数内容，所以后续如果是标准篇幅则需要进行参数转换
        if (ObjectUtil.isEmpty(unSealPdfUrlResult)) {
            throw new BusinessException("文书生成失败");
        }
        String unSealPdfUrl = unSealPdfUrlResult.get("fileUrl");
        // 生成带签章的文书
        String pdfSealUrl = "";
        if (isDeptSign) {
            FileSealInfoQueryDto queryDto = new FileSealInfoQueryDto();
            SysDepartParam sysDepartParam = sysDepartParamService.getSysDepartParamByOrgCodeAndDeptCode(userInfo.getOrgCode(), userInfo.getDeptCode());
            queryDto.setUniscid(sysDepartParam.getUnicode());
            queryDto.setFileBase64(unSealPdfUrlResult.get("fileBase64"));
            queryDto.setDeptCode(userInfo.getDeptCode());
            pdfSealUrl = dealFileSeal(queryDto);
        }
        if (!isDeptSign && Boolean.TRUE.equals(afterSign)) {
            //若部门不用签章，且用户已经签字，则把用户签字后的url赋值进去
            pdfSealUrl = unSealPdfUrl;
        }

        //标准文书数据设置
        if (DocumentTemplateTypeEnum.STANDARD_TEMPLATE.getMappingCode().equals(pdfRequest.getTemplateType())) {
            caseDocumentRecord.setDocumentStandardContent(JSON.toJSONString(paramMap));
            caseDocumentRecord.setDocumentStandardUrl(unSealPdfUrl);
            caseDocumentRecord.setDocumentStandardUrlAfterSeal(pdfSealUrl);
            if (Boolean.TRUE.equals(afterSign)) {
                caseDocumentRecord.setDocumentStandardUrlAfterSign(pdfSealUrl);
            }
            return;
        }
        //窄幅文书数据设置
        caseDocumentRecord.setDocumentContent(JSON.toJSONString(paramMap));
        caseDocumentRecord.setDocumentUrl(unSealPdfUrl);
        caseDocumentRecord.setDocumentUrlAfterSeal(pdfSealUrl);
        if (Boolean.TRUE.equals(afterSign)) {
            caseDocumentRecord.setDocumentUrlPrint(pdfSealUrl);
            caseDocumentRecord.setDocumentUrlAfterSign(pdfSealUrl);
        }
    }

    /**
     * 深克隆&转换标准模版文书参数
     *
     * @param configBusiParamDocumentInfo 文书参数配置
     * @param pdfRequest                  文书生成请求
     * @return
     */
    private FillAndConvertToPdfRequest convertNarrowToStandardParam(ConfigBusiParamDocumentInfo configBusiParamDocumentInfo, FillAndConvertToPdfRequest pdfRequest) {
        //深克隆对象用于后续处理，不影响原参数
        if (!DocumentTemplateTypeEnum.STANDARD_TEMPLATE.getMappingCode().equals(pdfRequest.getTemplateType())) {
            return pdfRequest;
        }
        FillAndConvertToPdfRequest request = JSONObject.parseObject(JSONObject.toJSONString(pdfRequest),
                FillAndConvertToPdfRequest.class);
        request.setParamMap(ZtcDocumentParamEnum.convertNarrowToStandardParams(DocumentKindEnum.parseByCode(configBusiParamDocumentInfo.getDocumentKindCode()), request.getParamMap()));
        return request;
    }

    /**
     * 构建标准和窄幅文书，并填充文书记录信息，根据文书记录中的文书号生成文书pdf
     *
     * @param userInfo                    用户信息
     * @param pdfRequest                  文书参数
     * @param detailByDocumentCatalogCode 文书配置
     * @param caseDocumentRecord          文书记录数据
     * @param afterSign                   是否签字
     */
    private void generateStandardAndNarrowDocumentAndFillRecord(UserDTO userInfo, FillAndConvertToPdfRequest pdfRequest,
                                                                ConfigBusiParamDocumentInfo detailByDocumentCatalogCode,
                                                                AppCaseBeforeDocumentRecordNew caseDocumentRecord,
                                                                Boolean afterSign) {
        StopWatch stopWatch = new StopWatch();
        for (DocumentTemplateTypeEnum templateTypeEnum : DocumentTemplateTypeEnum.values()) {
            stopWatch.start(templateTypeEnum.getMappingCode() + "开始生成");
            pdfRequest.setTemplateType(templateTypeEnum.getMappingCode());
            //生成文书并填充文书记录数据
            generateDocumentAndFillRecord(userInfo, pdfRequest, detailByDocumentCatalogCode, caseDocumentRecord, afterSign);
            stopWatch.stop();
        }
        log.info("文书生成时间=>\r\n{}", stopWatch.prettyPrint());
    }

    /**
     * 描述：处理文书关联物品信息表
     *
     * @param saveDto    保存dto
     * @param documentId 文档id
     * @author shishengyao
     * @date 2023/02/21
     */
    private void dealModifyRelatedGoods(AppDocumentCommonSaveDto saveDto, String documentId) {
        String goodsList = "goodsList";
        if (ObjectUtil.isNotEmpty(documentId)) {
            // 删除原来的物品表信息
            Example example = new Example(AppDocumentRelatedGoods.class);
            example.createCriteria().andEqualTo("documentId", documentId);
            appDocumentRelatedGoodsMapper.deleteByExample(example);
        }
        HashMap<String, Object> dataMap = saveDto.getDataMap();
        if (!ObjectUtils.isEmpty(saveDto.getDataMap().get(goodsList))) {
            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(dataMap));
            JSONArray array = jsonObject.getJSONArray(goodsList);
            for (int i = 0; i < array.size(); i++) {
                AppDocumentRelatedGoods goods = JSON.parseObject(array.getJSONObject(i).toJSONString(), AppDocumentRelatedGoods.class);
                goods.setDocumentId(documentId);
                goods.setId(StringUtils.uuid());
                appDocumentRelatedGoodsMapper.insertSelective(goods);
            }
        }
    }


    /**
     * 描述：处理更新文书内容宽表
     *
     * @param saveDto
     * @param documentId 文档id
     * @param userInfo   用户信息
     * @return int
     * @author shishengyao
     * @date 2023/02/21
     */
    private void dealModifyAppDocumentInfoDetail(AppDocumentCommonSaveDto saveDto, String documentId, UserDTO userInfo) {
        AppDocumentInfoDetail appDocumentInfoDetail = new AppDocumentInfoDetail();
        BeanUtils.copyProperties(saveDto, appDocumentInfoDetail);
        appDocumentInfoDetail.setPartyName(StringUtils.isBlank(saveDto.getEntName()) ? saveDto.getPersonName() : saveDto.getEntName());
        appDocumentInfoDetail.setId(documentId);
        appDocumentInfoDetail.setDocumentCatalogCode(saveDto.getDocumentCatalogCode());
        appDocumentInfoDetail.setPartyType(saveDto.getDocumentObjectType());
        appDocumentInfoDetail.setUpdateTime(LocalDateTime.now());
        appDocumentInfoDetail.setUpdator(userInfo.getUserId().toString());
        //设置关联任务信息
        List<AssociatedTaskVo> associatedInfo = Optional.ofNullable(saveDto.getAssociatedInfo()).orElse(Collections.emptyList());
        //初始化关联任务时间
        associatedInfo.forEach(AssociatedTaskVo::initRelationTime);
        appDocumentInfoDetail.setAssociatedInfo(JSON.toJSONString(associatedInfo));

        // 询问通知书 复选框特殊梳理
        wxtzsCheckBoxsDeal(saveDto, appDocumentInfoDetail);

        // 反射设值
        try {
            List<BusiTableOperateVo> busiTableOperateVoList = configBusiParamDocumentColumnMapper.selectTableNameListByDocumentCatalogCode(saveDto.getDocumentCatalogCode());
            // 获取属性
            Field[] fields = AppDocumentInfoDetail.class.getDeclaredFields();
            HashMap<String, Object> insertMap = saveDto.getDataMap();
            HashMap<String, Object> insertTransferMap = new HashMap<>(64);
            /**
             * 带经纬度的地址，用统一的key 映射column表，根据文书目录编码判断区分
             */
            String commonLatAndLgtAddr = "addressWithLatAndLgt";
            if (ObjectUtil.isNotEmpty(insertMap.get(commonLatAndLgtAddr))) {
                JSONObject addrJson = JSONObject.parseObject(JSON.toJSONString(insertMap.get(commonLatAndLgtAddr)));
                if (ObjectUtil.isNotEmpty(addrJson)) {
                    // {address: "拱墅区西溪街道蓝天商务中心", lng: 120.14989, lat: 30.27751}
                    insertMap.put("ZTC_COMMON_ADDRESS", addrJson.getString("address"));
                    insertMap.put("ZTC_COMMON_LAT_AND_LGT", addrJson.getString("lng").concat(",").concat(addrJson.getString("lat")));
                }
            }
            // 转换key名
            for (BusiTableOperateVo busiTableOperateVo : busiTableOperateVoList) {
                Example example = new Example(ConfigBusiParamDocumentColumn.class);
                example.createCriteria().andEqualTo("documentCatalogCode", saveDto.getDocumentCatalogCode()).andEqualTo("busiTableNameEn", busiTableOperateVo.getBusiTableNameEn());
                List<ConfigBusiParamDocumentColumn> configBusiParamDocumentColumnList = configBusiParamDocumentColumnMapper.selectByExample(example);
                for (ConfigBusiParamDocumentColumn column : configBusiParamDocumentColumnList) {
                    for (Map.Entry<String, Object> entry : insertMap.entrySet()) {
                        if (entry.getKey().equals(column.getDocumentTemplateFieldEn())) {
                            insertTransferMap.put(column.getBusiColumnEn(), entry.getValue());
                        }
                    }
                }
            }
            // 将日期转换为正确类型
            for (Map.Entry<String, Object> entry : insertTransferMap.entrySet()) {
                if (entry.getKey().contains("date") || entry.getKey().contains("DATE") || entry.getKey().contains("time") || entry.getKey().contains("TIME")) {
                    if (entry.getValue() != null) {
                        if (entry.getValue().toString().contains("年")) {
                            if (entry.getValue().toString().contains("时")) {
                                entry.setValue(LocalDateTime.parse(entry.getValue().toString(), DateTimeFormatter.ofPattern("yyyy年M月d日H时mm分ss秒")));
                            } else {
                                entry.setValue(LocalDate.parse(entry.getValue().toString(), DateTimeFormatter.ofPattern("yyyy年M月d日")).atStartOfDay());
                            }
                        } else {
                            entry.setValue(LocalDateTime.parse(entry.getValue().toString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                        }
                    }
                }
            }
            // 反射设值
            for (Field f : fields) {
                if (f.isAnnotationPresent(Column.class)) {
                    for (Map.Entry<String, Object> entry : insertTransferMap.entrySet()) {
                        String mapKey = entry.getKey();
                        Object mapValue = entry.getValue();
                        // 根据属性上注解名
                        if (f.getAnnotation(Column.class).name().equals(mapKey)) {
                            Field insertField = appDocumentInfoDetail.getClass().getDeclaredField(f.getName());
                            insertField.setAccessible(true);
                            insertField.set(appDocumentInfoDetail, mapValue);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("保存详情表反射设值失败：", e);
            throw new BusinessException(e.getMessage());
        }
        int detailResult = appDocumentInfoDetailMapper.updateByPrimaryKeySelective(appDocumentInfoDetail);
        if (detailResult != 1) {
            throw new BusinessException("文书提交保存失败");
        }
    }

    /**
     * 办案直通车执法人员信息处理
     *
     * @param saveDto
     */
    private void dealModifyDocumentHandlePersonRecord(AppDocumentCommonSaveDto saveDto, String documentId) {
        //查询历史执法人员信息
        List<AppDocumentHandlePersonRecord> handlePersonRecordList = appDocumentHandlePersonRecordService.getAppDocumentHandlePersonByDocumentId(documentId);
        //有历史办案人员只修改协办人
        if (ObjectUtil.isNotEmpty(handlePersonRecordList) && handlePersonRecordList.size() > 0) {
            AppDocumentHandlePersonRecord updateRecord = new AppDocumentHandlePersonRecord();
            for (AppDocumentHandlePersonRecord personRecord : handlePersonRecordList) {
                if (HandlePersonTypeEnum.ASSIST.getCode().equals(personRecord.getHandlePersonType())) {
                    if (!personRecord.getHandlePersonId().equals(saveDto.getAssistHandleUserId())) {
                        updateRecord.setId(personRecord.getId());
                        updateRecord.setIsDelete(Constant.STRING_1);
                        appDocumentHandlePersonRecordMapper.updateByPrimaryKeySelective(updateRecord);
                        //协办人修改
                        AppDocumentHandlePersonRecord assistPersonRecord = new AppDocumentHandlePersonRecord();
                        assistPersonRecord.setHandlePersonType(HandlePersonTypeEnum.ASSIST.getCode());
                        assistPersonRecord.setHandlePersonName(saveDto.getAssistHandleUser());
                        assistPersonRecord.setHandlePersonTel(saveDto.getAssistHandleTel());
                        assistPersonRecord.setHandleOrgCode(saveDto.getAssistHandleOrgCode());
                        assistPersonRecord.setHandleOrgName(saveDto.getAssistHandleOrgName());
                        assistPersonRecord.setHandleDeptCode(saveDto.getAssistHandleDeptCode());
                        assistPersonRecord.setHandleDeptName(saveDto.getAssistHandleDeptName());
                        assistPersonRecord.setAppDocumentId(documentId);
                        assistPersonRecord.setHandlePersonId(saveDto.getAssistHandleUserId());
                        assistPersonRecord.setDingId(saveDto.getAssistHandleDingId());
                        assistPersonRecord.setId(BaseUtil.createUid());
                        updateRecord.setIsDelete(Constant.STRING_1);
                        appDocumentHandlePersonRecordMapper.insertSelective(assistPersonRecord);
                    } else {
                        updateRecord.setHandlePersonName(saveDto.getAssistHandleUser());
                        updateRecord.setHandlePersonTel(saveDto.getAssistHandleTel());
                        updateRecord.setHandleOrgCode(saveDto.getAssistHandleOrgCode());
                        updateRecord.setHandleOrgName(saveDto.getAssistHandleOrgName());
                        updateRecord.setHandleDeptCode(saveDto.getAssistHandleDeptCode());
                        updateRecord.setHandleDeptName(saveDto.getAssistHandleDeptName());
                        updateRecord.setDingId(saveDto.getAssistHandleDingId());
                        updateRecord.setId(personRecord.getId());
                        appDocumentHandlePersonRecordMapper.updateByPrimaryKeySelective(updateRecord);
                    }
                }

            }
        } else {
            dealDocumentHandlePersonRecord(saveDto, documentId);
        }


    }

    /**
     * 描述： 图片base64转成oss地址
     *
     * @return {@link String}
     * @author: zhengqiang
     * @date: 2023/5/22
     * @param: base64String
     **/
    @Override
    public String base64ToOssUrl(String base64String) {
        try {
            Base64ToMultipartFileUtil fileUtil = new Base64ToMultipartFileUtil(base64String);
            FileInfoSaveDto fileInfo = new FileInfoSaveDto();
            fileInfo.setFileBytes(fileUtil.getBytes());
            fileInfo.setFileTransferForm(FileTransferFormEnum.FILE_TRANSFER_FORM_3.getCode());
            fileInfo.setFileType(AttachmentRequestContentTypeEnum.png.getCode());
            Result result = iOssOperateService.uploadFile(fileInfo);
            if (HttpStatus.HTTP_OK == result.getCode()) {
                return result.getData().toString();
            } else {
                throw new BusinessException("数据处理异常:" + result.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("数据处理异常");
        }
    }

    /**
     * 描述： 图片base64转成oss地址
     *
     * @return {@link String}
     * @author: zhengqiang
     * @date: 2023/5/22
     * @param: base64String
     **/
    @Override
    public String base64PdfToOssUrl(String base64String) {
        try {
            Base64ToMultipartFileUtil fileUtil = new Base64ToMultipartFileUtil(base64String);
            FileInfoSaveDto fileInfo = new FileInfoSaveDto();
            fileInfo.setFileBytes(fileUtil.getBytes());
            fileInfo.setFileTransferForm(FileTransferFormEnum.FILE_TRANSFER_FORM_3.getCode());
            fileInfo.setFileType(AttachmentRequestContentTypeEnum.pdf.getCode());
            Result result = iOssOperateService.uploadFile(fileInfo);
            if (HttpStatus.HTTP_OK == result.getCode()) {
                return result.getData().toString();
            } else {
                throw new BusinessException("数据处理异常:" + result.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("数据处理异常");
        }
    }

    /**
     * 下载重庆文件
     */
    @Override
    public String getFileByteByFileId(String fileId) {
//        // todo 测试
//        File file = new File("C:\\Users\\hzhb\\Desktop\\处罚\\下载的印章编码.txt");
//        String base64Str = cn.hutool.core.io.FileUtil.readString(file,"utf-8");
//        return base64Str;
        HashMap<String, Object> param = new HashMap<>();
        //签章Id
        param.put("fileId", fileId);
        Result result = PunishMainClientUtil.httpGet(PunishMainServicePortUriConstant.GETFILEBYTEBYFILEID, param);
        if (TWO_HUNDRED != result.getCode()) {
            logger.info(" 获取重庆下载文件失败,文件id:{},  result:{}", fileId, result.getMessage());
            throw new BusinessException(result.getMessage());
        }
        return (String) result.getData();
    }

    @Override
    public Map<String, Object> receiveSignFileId(AppDocumentSignDto saveDto) {
        // 这个应该是签完字的文件. 转换签章的文件id 获取文件流, 将文件流转换问base64的地址.
        String base64Str = getFileByteByFileId(saveDto.getFileId());
        saveDto.setSignFile(base64Str);

        //文书为送达地址确认书
        ConfigBusiParamDocumentInfo detailByDocumentCatalogCode = configBusiParamDocumentInfoService.getDetailByDocumentCatalogCode(saveDto.getDocumentCatalogCode());
        String kindCode = detailByDocumentCatalogCode.getDocumentKindCode();
        CaseDocumentRecord caseDocumentRecord = caseDocumentRecordMapper.selectByPrimaryKey(saveDto.getDocumentId());
        if (DocumentKindEnum.DOC_KIND_SDDZQRS.getCode().equals(kindCode) && ObjectUtil.isNotEmpty(caseDocumentRecord)) {
            if (ObjectUtil.isNotEmpty(caseDocumentRecord.getCaseId())) {
                CaseDocumentRecordSignSaveDto dto = new CaseDocumentRecordSignSaveDto();
                BeanUtils.copyProperties(saveDto, dto);
                return caseDocumentRecordService.receiveSignFileOfCaseDocChongQing(dto);
            }
        }
        //详情表字段保存
        AppDocumentInfoDetail appDocumentInfoDetail = appDocumentInfoDetailMapper.selectByPrimaryKey(saveDto.getDocumentId());
        if (appDocumentInfoDetail != null) {
            appDocumentInfoDetail.setSignFile(saveDto.getSignFile());
            appDocumentInfoDetail.setFingerPrint(saveDto.getFingerprint());
            appDocumentInfoDetailMapper.updateByPrimaryKeySelective(appDocumentInfoDetail);
        } else {
            throw new BusinessException("文书不存在，请检查");
        }
        // 文书表更新
        AppCaseBeforeDocumentRecordNew appCaseBeforeDocumentRecordNew = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(saveDto.getDocumentId());
        if (appCaseBeforeDocumentRecordNew == null) {
            throw new BusinessException("文书不存在，请检查");
        }
        JSONObject jsonObject = JSON.parseObject(appCaseBeforeDocumentRecordNew.getDocumentContent());

        // 合并 签字和按手印
//        String base64Str = ImageUtil.overlapImage(saveDto.getSignFile(), saveDto.getFingerprint());
        // 转换为oos地址
        String ossUrl = base64PdfToOssUrl(base64Str);

        if (StringUtils.isNotBlank(saveDto.getPersonnelType())) {
            // 当事人
            if (saveDto.getPersonnelType().equals(Constant.STRING_1)) {
                jsonObject.put("signFingerprintPic", ossUrl);
                jsonObject.put("signFingerprintDate", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年M月d日")));
            } else {
                jsonObject.put("signFingerprintPicWitness", ossUrl);
                jsonObject.put("signFingerprintDateWitness", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年M月d日")));
            }
        } else {
            jsonObject.put("signFingerprintPic", ossUrl);
            jsonObject.put("signFingerprintDate", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy年M月d日")));
        }

        appCaseBeforeDocumentRecordNew.setDocumentContent(jsonObject.toJSONString());
        // 重新生成文书
        List<ConfigBusiParamDocumentInfo> configBusiParamDocumentInfos = getConfigBusiParamDocumentInfos(saveDto.getDocumentCatalogCode());
        String templateCode = getTemplateCodeByDocumentCatalogCode(configBusiParamDocumentInfos, appDocumentInfoDetail.getPartyType(), null);
        HashMap<String, Object> jsonMap = new HashMap<>(64);
        for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
            jsonMap.put(entry.getKey(), entry.getValue());
        }
        FillAndConvertToPdfRequest pdfRequest = assemblySignPdfRequest(kindCode, templateCode, jsonMap);
        Map<String, String> unSealPdfUrl = getConvertedPdfUrl(pdfRequest);
        // todo 签字盖章的 oos
        String pdfSealUrl = ossUrl;
        // 未签章的文件 oos
        String unSealPdfUrlStr = unSealPdfUrl.get("fileUrl");
//        if (Constant.STRING_1.equals(detailByDocumentCatalogCode.getIsDeptSign())) {
//            FileSealInfoQueryDto queryDto = new FileSealInfoQueryDto();
//            SysDepartParam sysDepartParam = sysDepartParamService.getSysDepartParamByOrgCodeAndDeptCode(userDTO.getOrgCode(), userDTO.getDeptCode());
//            queryDto.setUniscid(sysDepartParam.getUnicode());
//            queryDto.setFileBase64(unSealPdfUrl.get("fileBase64"));
//            queryDto.setDeptCode(userDTO.getDeptCode());
//            pdfSealUrl = dealFileSeal(queryDto);
//        } else {
//            pdfSealUrl = unSealPdfUrl.get("fileUrl");
//        }
        //
        appCaseBeforeDocumentRecordNew.setDocumentUrlPrint(pdfSealUrl);
        // 返回
        Map<String, Object> resultMap = new HashMap<>(16);
        resultMap.put("success", "true");
        resultMap.put("pdfSealUrl", pdfSealUrl);
        appCaseBeforeDocumentRecordNew.setDocumentUrlAfterSign(pdfSealUrl);
        appCaseBeforeDocumentRecordNew.setDocumentUrlPrint(unSealPdfUrlStr);
        appCaseBeforeDocumentRecordNew.setSignTime(LocalDateTime.now());
        appCaseBeforeDocumentRecordNew.setDocumentSignstampedStatus(DocumentStatusEnum.CONFIRM_END.getCode());
        appCaseBeforeDocumentRecordMapper.updateByPrimaryKeySelective(appCaseBeforeDocumentRecordNew);
        return resultMap;
    }

    @Override
    public Result getOcrData(MultipartFile file) {
        Map<String, String> headers = HeaderUtil.headerInfo();
        File myFile = null;
        try {
            myFile = FileUtil.multipartFileToFile(file);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String response = HttpUtil.createPost(tzServiceUrl.concat("sign/getOcrData")).addHeaders(headers).form("file", myFile).execute().body();
        Result result = JSON.parseObject(response, Result.class);
        if (TWO_HUNDRED != result.getCode()) {
            logger.info(" 获取重庆ocr失败, result:{}", result.getMessage());
            throw new BusinessException(result.getMessage());
        }
        return result;
    }

    @Override
    public String getToken() {
        Map<String, String> headers = HeaderUtil.headerInfo();
        HashMap<String, Object> param = new HashMap<>();
        param.put("file", "");
        String response = HttpUtil.createGet(tzServiceUrl.concat("sign/getToken")).addHeaders(headers).form(param).execute().body();
        Result<String> result = JSON.parseObject(response, Result.class);
        if (TWO_HUNDRED != result.getCode()) {
            logger.info(" 获取重庆ocr失败, result:{}", result.getMessage());
            throw new BusinessException(result.getMessage());
        }
        return result.getData();
    }

    @Override
    public Result getCqEntList(EntQueryDto dto) {
        Map<String, String> headers = HeaderUtil.headerInfo();
        String param = JSON.toJSONString(dto);
        String response = HttpUtil.createPost(tzServiceUrl.concat("punish/common/getUnitTreeList")).addHeaders(headers).body(param).execute().body();
        Result result = JSON.parseObject(response, Result.class);
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> sendSmsNotify(AppDocumentSendNotifyDto dto) {
        Map<String, String> headers = HeaderUtil.headerInfo();
        //记录短信发送记录
        appDocumentSendRecordMapper.insert(new AppDocumentSendRecord(dto.getDocumentId(), dto.getMobile()));
        //组装短信参数
        SendSmsDto smsDto = new SendSmsDto();
        smsDto.setMobiles(dto.getMobile());
        smsDto.setContent(assemblyZtcSmsNotify(dto));
        String param = JSON.toJSONString(smsDto);
        String response = HttpUtil.createPost(tzServiceUrl.concat("/punish/common/electric/sent/flow/sendSmsProvince")).addHeaders(headers).body(param).execute().body();
        return JSON.parseObject(response, Result.class);
    }

    /**
     * 获取关联任务列表
     */
    @Override
    public PageResponse<AssociatedTaskVo> getAssociatedTaskList(MyAssociatedTaskDto dto) {
        PageResponse<AssociatedTaskVo> convert = new PageResponse<>();
        if (AssociatedTaskTypeEnum.CASE_SOURCE.getCode().equals(dto.getType())) {
            // 获取我的案源-预调查阶段
            convert = caseSourceRegisterMainInfoService.myCaseSourceList(dto.getPageNum(), dto.getLength(), dto.getPartyNameOrCaseReason(), Constant.STRING_3);
        } else if (AssociatedTaskTypeEnum.CASE.getCode().equals(dto.getType())) {
            // 获取我的案件-调查取证阶段
            convert = caseMainInfoService.getMyCaseMainTaskList(CaseStageEnum.INVESTIGATION.getCode(), Constant.STRING_2, dto.getPartyNameOrCaseReason(), dto.getPageNum(), dto.getLength());
        } else {
            // 获取相关检查任务
            getCheckTaskList(dto, convert);
        }
        return convert;
    }

    /**
     * 获取当前用户为检查人员已检查且有异常的检查任务列表
     *
     * @param dto
     * @param convert
     */
    private void getCheckTaskList(MyAssociatedTaskDto dto, PageResponse<AssociatedTaskVo> convert) {
        Map<String, String> headers = HeaderUtil.headerInfo();
        JSONObject param = new JSONObject();
        param.put("pageNum", dto.getPageNum());
        param.put("length", dto.getLength());
        param.put("keyword", dto.getPartyNameOrCaseReason());
        String paramStr = JSONObject.toJSONString(param);
        String response = HttpUtil.createPost(member.concat(getTaskListUrl)).addHeaders(headers).body(paramStr).execute().body();
        JSONObject object = JSONObject.parseObject(response);
        if (!Constant.STRING_200.equals(object.getString("code"))) {
            throw new BusinessException("获取检查任务失败！");
        }
        PunishTaskPageVO data = JSON.parseObject(object.getString("data"), PunishTaskPageVO.class);
        List<AssociatedTaskVo> taskVos = data.getData().stream().map(AssociatedTaskVo::convertForCheckTask).collect(Collectors.toList());
        convert.setData(taskVos);
        convert.setRecordsTotal(data.getTotal());
    }

    /**
     * 获取关联任务当事人列表
     */
    @Override
    public List<AssociatedTaskPartiesVo> getAssociatedTaskParties(AssociatedTaskPartiesDto dto) {
        List<AssociatedTaskPartiesVo> voList;
        if (AssociatedTaskTypeEnum.CASE_SOURCE.getCode().equals(dto.getType())) {
            // 获取案源当事人
            List<CaseSourcePartyInfoVo> caseSourcePartyInfo = caseSourceRegisterMainInfoService.getCaseSourcePartyInfo(dto.getId());
            voList = caseSourcePartyInfo.stream().map(AssociatedTaskPartiesVo::convertForCaseSource).collect(Collectors.toList());
        } else if (AssociatedTaskTypeEnum.CASE.getCode().equals(dto.getType())) {
            // 获取案件的当事人
            voList = getCaseMainPartiesInfo(dto.getId());
        } else {
            // 获取检查任务检查对象信息
            List<ClientVO> dataList = getClientVOS(dto.getId());
            // 将结果过滤掉不是机构主体与个人主体的类型
            voList = dataList.stream().filter(data -> CheckLegalEntityTypeEnum.LEGAL_ORG_ENTITY.getCode().equals(data.getLegalEntityType())
                            || CheckLegalEntityTypeEnum.LEGAL_PERSON_ENTITY.getCode().equals(data.getLegalEntityType()))
                    .map(AssociatedTaskPartiesVo::convertForCheckTask).collect(Collectors.toList());
        }
        return voList;
    }

    /**
     * 获取检查任务的检查对象信息
     */
    private List<ClientVO> getClientVOS(String uId) {
        Map<String, String> headers = HeaderUtil.headerInfo();
        String response = HttpUtil.createGet(member.concat(getCheckTargetListUrl).concat(uId)).addHeaders(headers).execute().body();
        JSONObject object = JSONObject.parseObject(response);
        if (!Constant.STRING_200.equals(object.getString("code"))) {
            throw new BusinessException("获取检查任务失败！");
        }
        List<ClientVO> dataList = JSON.parseArray(object.getString("data"), ClientVO.class);
        if (CollectionUtils.isEmpty(dataList)) {
            logger.error("检查任务uid：{}，无对应的检查对象信息", uId);
            throw new BusinessException("检查任务无对应的检查对象信息");
        }
        return dataList;
    }

    /**
     * 获取案件的当事人
     */
    private List<AssociatedTaskPartiesVo> getCaseMainPartiesInfo(String id) {
        // 获取案件的个人当事人信息
        Example personExample = new Example(CasePartiesPersonInfo.class);
        personExample.createCriteria().andEqualTo("caseId", id);
        List<CasePartiesPersonInfo> personInfos = casePartiesPersonInfoMapper.selectByExample(personExample);
        List<AssociatedTaskPartiesVo> personList = personInfos.stream().map(AssociatedTaskPartiesVo::convertForCasePartiesPerson).collect(Collectors.toList());
        // 获取案件的单位当事人信息
        Example legalExample = new Example(CasePartiesLegalInfo.class);
        legalExample.createCriteria().andEqualTo("caseId", id);
        List<CasePartiesLegalInfo> legalInfos = casePartiesLegalInfoMapper.selectByExample(legalExample);
        List<AssociatedTaskPartiesVo> legalList = legalInfos.stream().map(AssociatedTaskPartiesVo::convertForCasePartiesLegal).collect(Collectors.toList());
        personList.addAll(legalList);
        return personList;
    }

    @Override
    public PageResponse<AppCaseDocumentVo> page(AppDocQueryDto dto) {
        PageHelper.startPage(dto.getPageNum(), dto.getLength());
        AppHisDocQueryDto queryDto = new AppHisDocQueryDto();
        UserDTO userDTO = UserUtil.getUserInfo();
        queryDto.setQueryDocumentName(Constant.STRING_1);
        queryDto.setUserId(userDTO.getUserId().toString());
        queryDto.setOrgCode(userDTO.getOrgCode());
        queryDto.setDocObject(dto.getDocObject());
        return new PageResponse<>(appCaseBeforeDocumentRecordMapper.getHisDocumentList(queryDto))
                .convert(AppCaseDocumentVo::convert);
    }


    /**
     * 组装直通车送达通知短信内容
     *
     * @param dto
     * @return
     */
    private String assemblyZtcSmsNotify(AppDocumentSendNotifyDto dto) {
        AppCaseBeforeDocumentRecordNew record = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(dto.getDocumentId());
        if (Objects.isNull(record)) {
            throw new BusinessException("没有找到相应的文书信息");
        }
        if (StringUtils.isEmpty(record.getDocumentUrlAfterSign())) {
            throw new BusinessException("当前文书未确认无法发送短信通知");
        }
        //查询部门信息
        SysDepartParam sysDepartParam = sysDepartParamService.getSysDepartParamByOrgCodeAndDeptCode(record.getOrgCode(), record.getDeptCode());
        //查询文书详情
        AppDocumentInfoDetail detailInfo = appDocumentInfoDetailMapper.selectByPrimaryKey(dto.getDocumentId());
        if (Objects.isNull(detailInfo)) {
            throw new BusinessException("没有找到相应的文书信息详情");
        }
        return StrFormatter.format("{}你好，现向你(单位)送达{}于{}作出的{}{}，{}，请查收。",
                //当事人姓名
                dealNullStrEmpty(String.valueOf(Constant.INTEGER_1).equals(detailInfo.getPartyType()) ? detailInfo.getPersonName() : detailInfo.getEntName()),
                //部门全称
                dealNullStrEmpty(sysDepartParam.getOrgStandardName()),
                //发送日期和时间
                dealNullStrEmpty(cn.hutool.core.date.DateUtil.now()),
                //文书名称，
                dealNullStrEmpty(record.getDocumentName()),
                //文书编号
                dealNullStrEmpty(record.getDocumentNumber()),
                //文书url
                dealNullStrEmpty(record.getDocumentUrlAfterSign())
        );
    }

    /**
     * 处理null为空字符串
     *
     * @param content
     * @return
     */
    private String dealNullStrEmpty(String content) {
        return StrUtil.isEmpty(content) ? "" : content;
    }


    /**
     * 不签字提交
     *
     * @param dto
     * @return
     */
    @Override
    public String submitWithoutSignature(SubmitWithoutSignatureDto dto) {
        AppDocumentInfoDetail appDocumentInfoDetail = appDocumentInfoDetailMapper.selectByPrimaryKey(dto.getDocumentId());
        if (Objects.isNull(appDocumentInfoDetail)) {
            throw new BusinessException("文书不存在，请检查");
        }
        AppDocumentSignSaveDto saveDto = new AppDocumentSignSaveDto();
        saveDto.setDocumentId(appDocumentInfoDetail.getId());
        saveDto.setDocumentCatalogCode(appDocumentInfoDetail.getDocumentCatalogCode());
        saveDto.setNotSignReason(dto.getNotSignReason());
        saveDto.setNotSignReasonReplenish(dto.getNotSignReasonReplenish());
        Map<String, Object> stringObjectMap = receiveSignFile(saveDto);
        return MapUtils.getString(stringObjectMap, "documentId", "");
    }

    @Override
    public String signAgain(SignAgainDto dto) {
        // 校验关联任务的状态
        verifyAssociatedTask(dto.getDocumentId(), OpTypeEnum.SIGN_AGAIN.getErrorMessage());
        UserDTO userInfo = getUser();
        String documentId = dto.getDocumentId();
        AppCaseBeforeDocumentRecordNew oldDocumentRecord = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(documentId);
        if (ObjectUtil.isEmpty(oldDocumentRecord)) {
            throw new BusinessException("文书id：{" + documentId + "}不存在");
        }
        // 将数据加入历史表
        insertDocumentRecordHis(userInfo, oldDocumentRecord, OpTypeEnum.SIGN_AGAIN.getCode());
        // 进行重新签字
        AppDocumentSignSaveDto saveDto = new AppDocumentSignSaveDto();
        saveDto.setDocumentCatalogCode(oldDocumentRecord.getDocumentCatalogCode());
        saveDto.setDocumentId(oldDocumentRecord.getId());
        saveDto.setSignFile(dto.getSignFile());
        Map<String, Object> stringObjectMap = receiveSignFile(saveDto);
        return MapUtils.getString(stringObjectMap, "documentId", "");
    }

    @Override
    public Result<String> deleteDocument(DeleteDocumentDto dto) {
        // 校验关联任务的状态
        verifyAssociatedTask(dto.getDocumentId(), OpTypeEnum.DELETE.getErrorMessage());
        UserDTO userInfo = getUser();
        String documentId = dto.getDocumentId();
        AppCaseBeforeDocumentRecordNew oldDocumentRecord = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(documentId);
        if (ObjectUtil.isEmpty(oldDocumentRecord)) {
            throw new BusinessException("文书id：{" + documentId + "}不存在");
        }
        // 将数据加入历史表
        insertDocumentRecordHis(userInfo, oldDocumentRecord, OpTypeEnum.DELETE.getCode());
        /*
         * 只删除主表信息
         * 案件文书记录表-TRJ app_case_before_document_record
         */
        appCaseBeforeDocumentRecordMapper.deleteByPrimaryKey(documentId);
        // 执行检查对象删除文书的钩子方法
        String kindCode = getKindCodeByDocumentId(documentId);
        ZtcSourceTypeEnum sourceType = Optional.ofNullable(ZtcSourceTypeEnum.getZtcSourceTypeEnumByCode(oldDocumentRecord.getSourceType()))
                .orElse(ZtcSourceTypeEnum.CF_ZTC);
        BaseZtcSourceTypeHook.getHook(sourceType, applicationContext)
                .appCaseDeleteHook(new CheckObjectZtcSourceTypeDto()
                        .setSourceId(null)
                        .setDocumentId(dto.getDocumentId())
                        .setSourceType(sourceType)
                        .setTaskOrgId(null)
                        .setDocumentKindEnum(DocumentKindEnum.getEnumByCode(kindCode)));
        return Result.success(Constant.STRING_OPERATE_SUCCESS);
    }

    /**
     * 根据documentId获取kindCode
     *
     * @param documentId
     * @return
     */
    private String getKindCodeByDocumentId(String documentId) {
        AppDocumentInfoDetail appDocumentInfoDetail = appDocumentInfoDetailService.selectByPrimaryKey(documentId);
        String documentCatalogCode = appDocumentInfoDetail.getDocumentCatalogCode();
        return getKindCodeByCatalogId(documentCatalogCode);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String generateSealPicAgain(String documentId) {
        AppCaseBeforeDocumentRecordNew record = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(documentId);
        if (Objects.isNull(record)) {
            throw new BusinessException("没有找到相应的文书信息");
        }
        JSONObject paramMap = JSON.parseObject(record.getDocumentContent());
        String orgStandardNameSeal = paramMap.getString("orgStandardNameSeal");
        String sealDate = paramMap.getString("sealDate");
        String sealPic = docCommonOperateService.getSealPreviewInfo(orgStandardNameSeal, sealDate, record.getOrgCode(), record.getDeptCode());
        //设置窄幅文书参数
        paramMap.put("sealPic", sealPic);
        //【v1.3.4】设置宽幅文书参数，兼容历史数据没有该字段防止抛出异常
        String documentStandardContent = record.getDocumentStandardContent();
        if (StrUtil.isNotEmpty(documentStandardContent)) {
            JSONObject standardParams = JSON.parseObject(documentStandardContent);
            standardParams.put("sealPic", sealPic);
            record.setDocumentStandardContent(JSON.toJSONString(standardParams));
        }
        record.setDocumentContent(JSON.toJSONString(paramMap));
        appCaseBeforeDocumentRecordMapper.updateByPrimaryKeySelective(record);
        return sealPic;
    }

    @Override
    public VerifyAssociatedTaskVo verifyAssociatedTask(VerifyAssociatedTaskDto dto) {
        try {
            verifyAssociatedTask(dto.getDocumentId(), OpTypeEnum.getErrorMessageByCode(dto.getType()));
            return new VerifyAssociatedTaskVo(true, null);
        } catch (BusinessException e) {
            logger.error("文书关联任务校验失败：" + e.getMessage());
            return new VerifyAssociatedTaskVo(false, e.getMessage());
        }
    }

    @Override
    public String getDocumentUrlByDocumentId(String documentId) {
        if (StrUtil.isBlank(documentId)) {
            throw new BusinessException("文书id不能为空！");
        }
        AppCaseBeforeDocumentRecordNew documentRecord = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(documentId);
        if (Objects.isNull(documentRecord)) {
            throw new BusinessException("无相关文书信息！");
        }
        String url = StrUtil.isNotBlank(documentRecord.getDocumentUrlAfterSign()) ?
                documentRecord.getDocumentUrlAfterSign() : documentRecord.getDocumentUrlAfterSeal();
        if (url.startsWith("http://23.99.94.216:33180/fastdfs")) {
            url = url.replace("http://23.99.94.216:33180/fastdfs", "http://183.230.113.144:41130/fastdfs");
        }
        return url;
    }

    /**
     * 判断直通车文书的关联任务状态是否允许修改
     * 1.已关联案源，且案源已处置完成的，点此则提示用户“案源已处置完成，不支持重新签字”
     * 2.已关联案件，且案件已经过了调查取证阶段，点此则提示用户“调查已完成，不支持重新签字”
     */
    private void verifyAssociatedTask(String documentId, String opErrorMessage) {
        // 得到宽表信息
        AppDocumentInfoDetail appDocumentInfoDetail = appDocumentInfoDetailMapper.selectByPrimaryKey(documentId);
        // 得到签字状态信息
        AppCaseBeforeDocumentRecordNew appCaseBeforeDocumentRecordNew = appCaseBeforeDocumentRecordMapper.selectByPrimaryKey(documentId);
        if (Objects.isNull(appDocumentInfoDetail) || Objects.isNull(appCaseBeforeDocumentRecordNew)) {
            throw new BusinessException("文书信息不存在，请检查");
        }
        if (!DocumentStatusEnum.CONFIRM_END.getCode().equals(appCaseBeforeDocumentRecordNew.getDocumentSignstampedStatus())) {
            // 如果不是以确认状态，则不需要校验关联任务的状态
            return;
        }
        // 得到关联任务信息
        String associatedInfo = appDocumentInfoDetail.getAssociatedInfo();
        List<AssociatedTaskVo> taskVos = JSONArray.parseArray(associatedInfo, AssociatedTaskVo.class);
        // 存在关联任务信息，删除、重置文书、重新签字时则需要判断 案源与案件的任务状态
        if (!CollectionUtils.isEmpty(taskVos)) {
            for (AssociatedTaskVo taskVo : taskVos) {
                // 这里考虑到后期一个文书可能关联多个任务，将关联任务列表都进行一次判断
                verifyAssociatedTaskStatus(opErrorMessage, taskVo);
            }
        }
    }

    private void verifyAssociatedTaskStatus(String opErrorMessage, AssociatedTaskVo taskVo) {
        if (AssociatedTaskTypeEnum.CHECK_TASK.getCode().equals(taskVo.getType().getCode())) {
            // 检查任务不需要判断状态
            return;
        }
        if (AssociatedTaskTypeEnum.CASE.getCode().equals(taskVo.getType().getCode())) {
            // 校验案件状态是否允许操作
            verifyCaseMainStatus(opErrorMessage, taskVo);
        } else if (AssociatedTaskTypeEnum.CASE_SOURCE.getCode().equals(taskVo.getType().getCode())) {
            // 校验案源状态是否允许操作
            verifyCaseSourceStatus(opErrorMessage, taskVo);
        }
    }

    /**
     * 检查案源的状态是否为已处置状态，如果已处置则抛出异常
     */
    private void verifyCaseSourceStatus(String opErrorMessage, AssociatedTaskVo taskVo) {
        CaseSourceRegisterMainInfo caseSourceRegisterMainInfo = caseSourceRegisterMainInfoService.getCaseSourceRegisterMainInfoById(taskVo.getId());
        if (Objects.isNull(caseSourceRegisterMainInfo)) {
            // 案源信息为空 不做校验
            return;
        }// 已立案 不予立案 已移送 移送中 以上四种都属于案源已处置
        if (CaseSourceStatusEnum.REGISTERED.getIndex().equals(caseSourceRegisterMainInfo.getCaseSourceStatus())
                || CaseSourceStatusEnum.NO_REGISTERED.getIndex().equals(caseSourceRegisterMainInfo.getCaseSourceStatus())
                || CaseSourceStatusEnum.TRANSFER.getIndex().equals(caseSourceRegisterMainInfo.getCaseSourceStatus())
                || CaseSourceStatusEnum.TRANSFERRING.getIndex().equals(caseSourceRegisterMainInfo.getCaseSourceStatus())) {
            throw new BusinessException("案源已处置完成，" + opErrorMessage);
        }
    }

    /**
     * 检查案件的状态是否为调查取证阶段，如果不为调查取证阶段则抛出异常
     */
    private void verifyCaseMainStatus(String opErrorMessage, AssociatedTaskVo taskVo) {
        CaseMainInfo caseMainInfo = caseMainInfoService.getCaseMainInfoById(taskVo.getId());
        if (Objects.isNull(caseMainInfo)) {
            // 案件信息为空 不做校验
            return;
        }
        if (!CaseStageEnum.INVESTIGATION.getCode().equals(caseMainInfo.getCaseCurrentStageCode())
                || !CaseStatusEnum.HANDLING_CASE.getCode().equals(caseMainInfo.getCaseStatus())) {
            // 案件阶段不为调查取证阶段  &&  案件的状态不为办案中
            throw new BusinessException("调查已完成，" + opErrorMessage);
        }
    }
}
